Você está na página 1de 300

INTRODUO ORGANIZAO E PROGRAMAO DE COMPUTADORES

USANDO LOGISIM E SCILAB

OSVALDO CARVALHO
DEPARTAMENTO DE CINCIA DA COMPUTAO UFMG
OSVALDO@DCC.UFMG.BR

2 SEMESTRE DE 2013

Contedo

Contedo
1 Computadores e Informao .............................................................................................. 12 1.1 1.2 1.3 1.4 1.5 1.6 1.7 2 Computadores ............................................................................................................. 12 Informao Analgica e Digital ................................................................................... 18 Computadores e Informao ...................................................................................... 21 Converses anlogo-digital e digital-analgica ........................................................... 23 Sensores e atuadores .................................................................................................. 28 Memrias .................................................................................................................... 31 Organizao do Contedo ........................................................................................... 35

Circuitos Combinatrios ...................................................................................................... 42 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 Bits e cdigos ............................................................................................................... 42 lgebra de Boole ......................................................................................................... 47 Portas Lgicas e Transistores ...................................................................................... 50 Introduo ao Logisim ................................................................................................. 55 Soma de duas parcelas de 1 bit ................................................................................... 61 Soma de dois inteiros com vrios bits ......................................................................... 65 Modularizao e Sntese Automtica de Circuitos Combinatrios no Logisim ........... 69 Sntese de um display hexadecimal ............................................................................ 75 Comparao de binrios sem sinal.............................................................................. 77 Multiplexadores, Demultiplexadores e Decodificadores ............................................ 81

Circuitos Sequenciais........................................................................................................... 84 3.1 3.2 3.3 3.4 3.5 3.6 Flip-flops e Registradores ............................................................................................ 84 Barramentos e Controle de Fluxo de Dados ............................................................... 88 Memrias .................................................................................................................... 89 Acumuladores e Loops ................................................................................................ 91 Uma Calculadora ......................................................................................................... 92 Clocks........................................................................................................................... 94

Processadores ..................................................................................................................... 98 4.1 4.2 4.3 4.4 4.5 Programa Armazenado ............................................................................................... 98 CPU-0: Um Primeiro Processador ............................................................................. 101 CPU-1: Processador com Instrues de Desvio ......................................................... 106 CPU-2: Processador com Instrues de Desvio Condicional ..................................... 109 CPUs Reais: Instrues e Programao em Assembler ............................................. 111

Contedo 5 Programas Scilab ............................................................................................................... 118 5.1 5.2 5.3 5.4 5.5 5.6 5.7 6 Compiladores, Interpretadores e Sistemas Operacionais ......................................... 118 Scilab ......................................................................................................................... 121 Variveis e Comandos de Atribuio......................................................................... 122 Usando o Scilab como Calculadora ........................................................................... 127 Programas Scilab ....................................................................................................... 132 Valores Lgicos e Strings ........................................................................................... 138 Os comandos if-then-else e printf ............................................................ 141

Matrizes............................................................................................................................. 145 6.1 6.2 6.3 6.4 6.5 6.6 6.7 Matrizes e Comandos de Atribuio ......................................................................... 145 Aritmtica matricial ................................................................................................... 148 Construindo matrizes ................................................................................................ 152 Matrizes e Grficos .................................................................................................... 154 Grficos 3D ................................................................................................................ 157 Matrizes de Strings .................................................................................................... 159 Matrizes e Expresses Lgicas .................................................................................. 161 O comando while ................................................................................................... 163 Loop para o Clculo de Fatorial ................................................................................. 164 Loop para o Clculo da Soma dos Elementos de um Vetor ...................................... 165 Loop para encontrar o Menor Valor presente em um Vetor .................................... 166 Loop para encontrar o Mximo Divisor Comum usando o Algoritmo de Euclides ... 167 O comando for ........................................................................................................ 169 Gerao e Impresso de Tabelas .............................................................................. 170 Comandos Aninhados................................................................................................ 173 Gerao e Impresso de uma Tabuada de Multiplicao ......................................... 175 Arquivos .................................................................................................................... 176 Matrizes de Strings e Arquivos .................................................................................. 178 Matrizes Numricas e Arquivos ................................................................................ 179 Desenhando Mapas................................................................................................... 181

Loops ................................................................................................................................. 163 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 7.10 7.11 7.12 7.13

Funes ............................................................................................................................. 185 8.1 8.2 8.3 8.4 8.5 Funes e Reaproveitamento de Cdigo .................................................................. 185 Forma e Funcionamento ........................................................................................... 187 Funes, arquivos fonte e o Scilab ............................................................................ 189 Funes e Encapsulamento de Detalhes (e mais sobre arquivos) ............................ 190 Funes e Desenvolvimento Top-down .................................................................... 193

Contedo 8.6 9 Funes Recursivas ................................................................................................... 195

Algoritmos, Pesquisa ......................................................................................................... 198 9.1 9.2 9.3 Definio e Caractersticas ........................................................................................ 198 Fatorao................................................................................................................... 200 Pesquisa..................................................................................................................... 206 Pesquisa Seqencial .......................................................................................... 206 Pesquisa Binria ................................................................................................ 207

9.3.1 9.3.2 10 10.1 10.2 10.3 10.4 11

Ordenao ..................................................................................................................... 210 Seleo e Troca.......................................................................................................... 210 Intercalao (MergeSort) .......................................................................................... 215 Partio (QuickSort) .................................................................................................. 219 Dividir para Conquistar.............................................................................................. 224 Algoritmos Numricos ................................................................................................... 228 11.1.1 11.1.2 11.1.3 Integrao por Trapzios ................................................................................... 228 Bisseo ............................................................................................................. 232 Srie de Taylor para exp(x) e Cancelamento Catastrfico ................................ 237 Complexidade da Ordenao ............................................................................ 242 Problemas NP-completos: O Problema do Caixeiro Viajante ........................... 246 Problemas indecidveis: O Problema da Correspondncia de Post .................. 253

12

Complexidade de Problemas......................................................................................... 242 12.1.1 12.1.2 12.1.3

13

Prximos Passos ............................................................................................................ 260

ndice Remissivo ........................................................................................................................ 264 Referncias ................................................................................................................................ 267 Apndice A: A CPU Pipoca ......................................................................................................... 271 A.1 1 2 3 4 5 6 7 8 9 Ciclo de Instruo ...................................................................................................... 272 Instrues ...................................................................................................................... 274 Programao em Assembler ......................................................................................... 276 Montagem do Programa Executvel ............................................................................. 278 O Circuito Principal da CPU Pipoca................................................................................ 279 O Contador de Programa .............................................................................................. 283 A Unidade de Controle .................................................................................................. 283 O Ciclo de Micro-Instruo............................................................................................ 287 O Micro-Programa......................................................................................................... 292 A Planilha Pipoca.xls ...................................................................................................... 295

Prefcio

Prefcio
Programao de Computadores a disciplina mais tradicionalmente oferecida por departamentos de Cincia da Computao, e geralmente tambm a de maior nmero de matrculas. Na UFMG, Programao de Computadores j era oferecida para Cincias e Engenharias alguns anos antes da criao do departamento. Seu cdigo DCC001, o que d uma ideia de sua venerabilidade. Este texto parte integrante de um conjunto de materiais pedaggicos para esta disciplina, produzidos com a inteno de serem usados em um curso de 60 horas-aula, dado em um semestre letivo. Exerccios, imprescindveis para um bom aprendizado, no esto aqui, mas em um site Moodle que contm tambm apresentaes, vdeos e outros materiais. O enfoque adotado apresenta algumas caractersticas que o distinguem da forma tradicional como a disciplina ministrada: O curso necessita de um professor e de monitores; Em cada semana so previstas uma aula expositiva, dada pelo professor, e uma aula prtica, dada pelos monitores; Aulas expositivas podem ser dadas em auditrio ou sala de aula com grande capacidade; Aulas prticas so oferecidas em laboratrios com computadores; melhores resultados podem ser esperados com turmas pequenas; Os procedimentos de avaliao do aluno incluem questionrios semanais e provas, que podem (e devem) ser realizados online; As aulas prticas tm como objetivo auxiliar os alunos nas avaliaes semanais; Uma base de questes, fechadas e abertas, est disponvel no Moodle para a montagem de avaliaes. Questes fechadas (mltipla escolha, associaes, etc.) so corrigidas automaticamente; ao montar uma avaliao, o professor deve dosar o uso de questes abertas para manter o trabalho de correo em volumes aceitveis. Conjuntos de exerccios podem tambm ser disponibilizados no Moodle, permitindo estudos e auto avaliaes pelos alunos; A linguagem adotada o Scilab; O primeiro tero do curso dedicado ao ensino de circuitos lgicos e organizao de computadores, utilizando o software Logisim 1 (Burch, 2002); Mesmo com um enfoque eminentemente prtico, o material cobre conceitos tericos fundamentais como complexidade de algoritmos, problemas np-completos e problemas indecidveis.

Com relao ao contedo, os pontos que provavelmente necessitam de maiores justificativas so (1) o estudo de organizao de computadores, (2) a adoo de Scilab, e (3) a incluso de material sobre complexidade e indecidibilidade. Qualquer curso introdutrio de Programao de Computadores tem que falar alguma coisa sobre computadores; ns tomamos a deciso de falar um pouco mais do que o tradicional. A nosso ver o estudo de organizao de computadores abre oportunidades para a introduo de diversos conceitos fundamentais para a programao de computadores. O aluno tem contato com bits, com operaes lgicas, com cdigos importantes como ASCII, inteiros sem sinal e ponto flutuante. Acumuladores so o primeiro contato com loops, e somadores so um
1

Carl Burch, Logisim - a graphical tool for designing and simulating logic circuits, acessado 7 de maro de 2011, http://ozark.hendrix.edu/~burch/logisim/.

Prefcio excelente exemplo de modularizao. A execuo sequencial de instrues e instrues de desvios so tambm elementos para a formao na mente do aluno de um mecanismo de execuo de programas. E, talvez mais importante, o primeiro contato com a programao se d sem a necessidade de abstraes com relao possibilidade de execuo de operaes bsicas. Para justificar a adoo do Scilab preciso falar um pouco sobre o fenmeno MatLab. MatLab, de Matrix Laboratory, uma linguagem chamada M e um ambiente de desenvolvimento e execuo voltado para aplicaes tcnicas. Segundo Bill McKeeman (um dos pioneiros do Computer Science Department de Stanford, hoje professor de Dartmouth e desenvolvedor da MathWorks2, empresa que vende e mantm o MatLab), a linguagem teve origem na ideia de colocar clculos matriciais em sua sintaxe, ao invs de utilizar chamadas de sub-rotinas como se faz em Fortran3. De uma forma geral, MatLab no conhecido em departamentos de Cincia da Computao, exceo dos que trabalham em reas como aprendizado de mquina ou viso computacional. No s aqui no Brasil que isto acontece. MatLab no foi projetado por especialistas em linguagens ou compiladores, no tendo aos olhos de cientistas da computao (incluindo este autor) importncia conceitual como linguagem de programao. Bryant et al4 chegam a afirmar que Matlab ... really is a language for manipulating matrices, not a general-purpose programming language. Pois mesmo no sendo uma linguagem de programao de propsito geral, MatLab tem os construtos bsicos de atribuio, deciso, repetio, recursividade e modularizao. Isso largamente suficiente para os propsitos deste curso, como pode ser visto nos muitos exemplos deste texto. Alm disso, o sucesso prtico do MatLab sem qualquer dvida enorme. Ao apresentar a linguagem M para o MIT em 2005, McKeeman inicia dizendo as it turns out, the computer science department is about the only part of MIT that does not use MatLab. Ele continua5: MATLAB has grown over 20 years from academic research into a generalized tool for a wide variety of applications, including vehicle crash simulation, financial prediction, genome analysis, imbedded computer control, aircraft design and so on. More than 200 MathWorks developers are working on the next release. Another 1000 people run the rest of the business, in Natick and worldwide. There are about a million users. Some MATLAB users do not think of what they are doing as "programming." Some users are interested in quick and easy results. Some users want to build applications that are bullet proof and reusable over decades. I know of 100000 line MATLAB programs and MATLAB programs mining petabytes of data and others running 100x parallel for days at a time. Some universities teach MATLAB for beginning programming. On every customer contact I find new surprises. MATLAB satisfies all these communities.

Mathworks, MathWorks - MATLAB and Simulink for Technical Computing, acessado 7 de maro de 2011, http://www.mathworks.com/. 3 Bill McKeeman, MATLAB 101 -- A talk for the MIT Computer Science Department, novembro de 2005, http://www.cs.dartmouth.edu/~mckeeman/references/matlab101/matlab101.html.
4

R.E. Bryant, K. Sutner, e M.J. Stehlik, Introductory Computer Science Education at Carnegie Mellon University: A Deans Perspective (Tech. Report CMU-CS-10-140, Carnegie Mellon University, Pittsburgh, 2010, http://link. cs. cmu. edu/article. php, 2010).
5

Bill McKeeman, MATLAB 101 -- A talk for the MIT Computer Science Department.

Prefcio O Scilab um sistema livre, produzido por um consrcio de organizaes francesas, que, sem tentar ser um clone, segue a mesma filosofia do MatLab. A compatibilidade das duas linguagens de programao grande mas no total. Segundo o verbete na Wikipedia, SciLab vem conquistando cada vez mais adeptos tanto na academia como na indstria. Existem livros sobre SciLab em ingls, francs e espanhol, e est disponvel na Internet um texto introdutrio em portugus produzido pelo Prof. Paulo Srgio da Mota Pires, da UFRN 6. Links para esses materiais podem ser encontrados no site 7 (Scilab Consortium, s.d.). O objetivo da incluso de conceitos mais sofisticados dar ao aluno noes intuitivas de complexidade e indecidibilidade, tornando-o capaz de caracterizar a eficincia de um programa de forma independente da velocidade de processadores, e aprendendo a reconhecer problemas cuja soluo por computadores pode demorar muito tempo, ou mesmo demorar um tempo no limitado. A abordagem , claro, muito introdutria, mas falamos de conceitos que constituem pilares da Cincia da Computao. No podemos perder o que frequentemente nossa nica oportunidade de um contato maior com estudantes que no tero outras disciplinas da Cincia da Computao. Quanto s avaliaes freqentes, a sua contribuio para a experincia de aprendizado consensual. Dentre as principais caractersticas de cursos altamente respeitados, levantadas pelo projeto Harvard Asssesssment Seminars8, esto: High demands and standards placed upon [students], but with plentiful opportunities to revise and improve their work before it receives a grade, thereby learning from their mistakes in the process. Frequent checkpoints such as quizzes, tests, brief papers, or oral exams. The key idea is that most students feel they learn best when they receive frequent evaluations, combined with the opportunity to revise their work and improve it over time.

Entretanto, avaliaes exigem correes e, com a atual presso por produtividade medida pela relao alunos/professor, o trabalho de correo pode se tornar insustentvel. preciso equilibrar o uso de questes fechadas, corrigidas automaticamente, com o de questes abertas, imprescindveis em um curso de programao de computadores mas que exigem correo manual. Mesmo controlando o uso de questes fechadas, o auxlio dado por uma equipe de monitores pode ser essencial para se manter avaliaes semanais. Este texto est organizado em 12 mdulos, que correspondem a 12 aulas expositivas com contedo novo. Isso se adapta bem a um semestre na UFMG, que tem aproximadamente 15 semanas. Com uma aula expositiva por semana, as trs semanas de folga podem ser completadas com revises ou outras atividades. Agradecimentos. A metodologia adotada para Programao de Computadores (uma aula expositiva e uma aula prtica por semana) e a nova linguagem (Scilab) me foram sugeridas pelos Professores Regina Helena Bastos Cabral e Ivan Moura Campos. Os dois me fizeram conhecer o Matlab, me convenceram da necessidade de prticas mais frequentes, e tambm da viabilidade de aplicao de provas online. A Regina j aplicava estas tcnicas com enorme sucesso em Clculo Numrico.

sciport-3.0.pdf, acessado 7 de maro de 2011, http://www.dca.ufrn.br/~pmotta/sciport3.0.pdf. 7 Scilab Consortium, Home - Scilab WebSite, acessado 7 de maro de 2011, http://www.scilab.org/. 8 Jack Chizmar, The Effective Teaching and Learning Network - training course and information for teachers - TQM and Classroom Research, acessado 7 de maro de 2011, http://www.etln.org.uk/resources/page16.html.

Prefcio Os monitores que trabalharam na disciplina em sua primeira oferta em 2007 foram Maxstaley Neves e Henrique Chevreux. Sem eles eu no teria conseguido enfrentar a mirade de detalhes tcnicos do Logisim, Moodle e Scilab, todos ento sistemas novos para mim. Mas, muito mais do que isso, eles forjaram para a monitoria uma postura ntegra, competente e criativa, postura que souberam transmitir aos outros monitores. A aplicao da metodologia faz uso intenso da infra-estrutura de tecnologia da informao da UFMG, competentemente administrada pelo Centro de Computao, pelo Laboratrio de Computao Cientfica, pelo Laboratrio de Recursos Computacionais do Instituto de Cincias Exatas e pelo Centro de Recursos Computacionais do Departamento de Cincia da Computao. A figura da capa foi retirada do fac-smile do manuscrito Dixit algorizmi 9, traduo do rabe para latim do trabalho de al-Khwrizm.

Muammad ibn Ms al-Khwrizm - Wikipedia, the free encyclopedia, acessado 21 de agosto de 2012, http://en.wikipedia.org/wiki/Mu%E1%B8%A5ammad_ibn_M%C5%ABs%C4%81_alKhw%C4%81rizm%C4%AB.

Computadores e Informao

12

1 Computadores e Informao
1.1 Computadores
Computadores eletrnicos programveis surgiram na dcada de 1940. Pouco mais de meio sculo aps a construo dos primeiros computadores, o impacto desta tecnologia sobre nossas vidas enorme. Computadores mudaram e muito a forma como se faz msica, cinema ou artes plsticas, como se escrevem textos, como se faz comrcio, medicina, engenharia, cincia, economia, como se namora, como governar e como exercer a cidadania. Mas o que um computador? Vamos comear com alguns exemplos. certo que voc j viu diversos computadores, e provvel que a imagem que lhe venha mente ainda seja similar mostrada na Figura 1.

Figura 1: Um IBM PC, lanado em 198110

Este o primeiro computador pessoal lanado pela IBM. Apesar de ter sido precedido desde os primeiros anos 70 por diversos outros micro-computadores, o lanamento em 1981 do IBM PC foi um marco a IBM era ento a empresa dominante na indstria da computao, provavelmente a nica capaz de lanar padres. A evoluo dos computadores foi enorme e se deu em direes de difcil previso. O sistema operacional do IBM PC que se afirmou sobre seus concorrentes foi o MS-DOS, fornecido pela Microsoft, ento uma pequena empresa que produzia compiladores para microcomputadores. O MS-DOS foi na verdade desenvolvido por Tim Patterson, da Seattle Computer Products, que por 50.000 dlares vendeu os direitos do sistema operacional que transformou a Microsoft no gigante atual. Faltou viso ao Tim Patterson? Sim, sem dvida. Um erro entretanto mais perdovel do que o da IBM, que na poca era maior ncleo de competncia mundial em computao. A IBM permitiu que o contrato com a Microsoft fosse feito sem exclusividade, liberando a venda do MS-DOS aos fabricantes de clones do IBM-PC. Poucos anos depois a Microsoft se tornou uma empresa maior do que a IBM.

10

IBM Archives: IBM Personal Computer, acessado 7 de maro de 2011, http://www 03.ibm.com/ibm/history/exhibits/pc/pc_1.html.

Computadores e Informao

13

Existem computadores que no se assemelham a PCs. Alis, os computadores existentes em maior nmero so simples e pequenos, e ficam escondidos em telefones celulares, iPods, eletrodomsticos e automveis.

Figura 2: A maioria dos computadores existentes est embarcada em carros, eletrodomsticos, telefones, ...

Outros so enormes, ocupando vastos sales, como o Blue Gene mostrado na Figura 3. Em 2006 o Blue Gene era o computador mais poderoso do mundo, sendo capaz de executar 478 trilhes de operaes aritmticas por segundo. Em 2008 j no era: o RoadRunner, que como o Blue Gene foi produzido pela IBM, atingiu 1 petaflops, isto , mil trilhes, ou 1015 operaes aritmticas por segundo. A ttulo de comparao, em 2012, a potncia de um PC de topo da ordem de gigaflops, ou 109 operaes aritmticas por segundo. Como curiosidade, o RoadRunner utiliza chips (circuitos integrados) usados na PlayStation 3 da Sony.

Figura 3: O supercomputador Blue Gene 11

11

Lawrence Livermore National Laboratory, BlueGene/L Photo Gallery, acessado 11 de maro de 2011, https://asc.llnl.gov/computing_resources/bluegenel/photogallery.html.

Computadores e Informao

14

A cada seis meses uma lista com os maiores computadores do mundo publicada no site da organizao Top500 12. Na lista de novembro de 2010, pela primeira vez o topo da lista foi ocupado por um computador chins, o Tianhe-1A, com um desempenho de 2,6 petaflops. Na lista de novembro de 2012 o primeiro lugar do computador Titan Cray XK7, que atingiu 17 petaflops. Vale a pena visitar este site, que contm dados e anlises interessantes sobre a evoluo dos supercomputadores, denominao que a indstria d a computadores como o Blue Gene, Tianhe-1A ou Titan. Com a rpida evoluo da eletrnica, super hoje, normal amanh, fraco depois de amanh. Para ter alguma utilidade o termo supercomputador forosamente relativo poca: um supercomputador um computador que figura dentre os mais poderosos do mundo ... em sua gerao.

Figura 4: O supercomputador Eniac, construdo em 1946 13

12

Home | TOP500 Supercomputing Sites, acessado 7 de maro de 2011, http://www.top500.org/.


13

Computer History Museum - Timeline of Computer History, acessado 16 de fevereiro de 2012, http://www.computerhistory.org/timeline/?year=1946.

Computadores e Informao Neste sentido o Eniac, construdo em 1946, e que conseguia fazer 385 multiplicaes em um segundo14, era mais super que o Blue Gene ou que o K-Computer, pois era mil vezes mais potente que seus predecessores. guisa de comparao, o K-Computer foi apenas 4 vezes mais rpido que seus predecessores, fator que hoje considerado muito alto ... O Eniac foi ainda mais do que mais veloz que seus predecessores: foi o primeiro computador com programa armazenado, capaz de resolver problemas genricos.

15

Figura 5: Alan Turing 15

Computadores transformam informao. Um fato muito importante sobre computadores que, desde que meios de armazenamento externo de informao (discos e fitas magnticas, por exemplo) estejam disponveis em quantidade suficiente, todos, pequenos e grandes, so capazes de realizar as mesmas transformaes de informao. As computaes nome tcnico para transformaes de informao que micro e supercomputadores conseguem realizar so as mesmas que um dispositivo terico, a mquina de Turing, capaz de fazer. Este dispositivo terico foi construdo com a ambio de capturar a noo de computabilidade, isto , da possibilidade de se resolver um problema de transformao de informao de forma efetiva, como uma composio de passos garantidamente realizveis. Isso foi proposto pelo matemtico ingls Alan Turing em 1937 16, alguns anos antes do funcionamento do primeiro computador eletrnico. As transformaes de informao possveis so as mesmas para computadores velozes e lentos, mas a velocidade com que a informao transformada pode diferir por vrias ordens de grandeza. Em muitos casos, a velocidade que determina em o valor da informao obtida. Qualquer computador pessoal, com disponibilidade de armazenamento externo suficiente,
14

ENIAC - Wikipedia, the free encyclopedia, acessado 16 de fevereiro de 2012, http://en.wikipedia.org/wiki/ENIAC.

Alan Turing - Wikipedia, the free encyclopedia, acessado 11 de maro de 2011, http://en.wikipedia.org/wiki/Alan_Turing.
15 16

Alan M. Turing, On Computable Numbers, with an Application to the Entscheidungsproblem, Proceedings of the London Mathematical Society s242, no 1 (1937): 230265.

Computadores e Informao

16

capaz de rodar um programa de previso meteorolgica para saber como estar o tempo no dia seguinte, mas possvel que ele gaste mais do que um dia nessa tarefa, o que anularia completamente o valor da informao produzida. Da mesma forma, se um computador deve produzir informao para ser exibida como um filme, uma velocidade abaixo da necessria torna inaceitvel o seu emprego.

Figura 6: Participao de pases em potncia computacional na lista dos 500 maiores (extrado de Top500 17)

A relao entre velocidade de produo de informao e seu valor se manifesta com bastante clareza na lista dos pases com maior potncia computacional instalada, mostrada na Figura 6.

Figura 7: O Blue Gene e seus mdulos18, sub-mdulos, sub-sub-mdulos, ...

A Figura 7 nos permite entender melhor a estrutura do Blue Gene: O sistema completo tem 64 racks, pequenas torres que ficam abrigadas nos grandes blocos do computador. Cada rack tem 32 ns computacionais. Um n computacional abriga 16 placas computacionais e, em alguns casos, at 2 placas de entrada e sada de dados. Cada placa computacional tem duas pastilhas (chips) de circuitos integrados. Cada chip abriga dois processadores, que so os circuitos que efetivamente realizam clculos computacionais.

17 18

Home | TOP500 Supercomputing Sites. SciDAC Review - SIMULATION SCALE: In HPC Simulations, How Much is ENOUGH?, acessado 2 de agosto de 2011, http://www.scidacreview.org/0801/html/scale.html.

Computadores e Informao

17

Na Figura 7 as sucessivas decomposies param por aqui mas, na verdade, um processador ainda uma estrutura bastante complexa.

Figura 8: Chip do processador Intel Core i7-980X19

Olhando para a imagem (Figura 8) de um chip do processador Intel Core i7-980X (este no o chip usado no Blue Gene), lanado em 2010, ns podemos visualmente distinguir ali diversos sub-mdulos. Se pudssemos olhar ainda mais de perto, veramos que este chip contm nada menos que 1,17 bilhes de transistores, espremidos em uma rea de apenas 248 milmetros quadrados. Fazendo agora um zoom na direo contrria, temos a Internet, a rede mundial que conecta quase todos os computadores do mundo. A imagem da Figura 9 propositalmente lembra uma galxia. So centenas de milhes de computadores na Internet, todos interligados.

19

Carlos Sosa e Knudson, Brant, IBM System Blue Gene Solution: Blue Gene/P Application Development, IBM Redbooks SG24-7287-03, acessado 14 de fevereiro de 2012, http://www.redbooks.ibm.com/redbooks/pdfs/sg247287.pdf.

Computadores e Informao

18

Figura 9: Uma visualizao da Internet pelo produzida pelo Projeto Opte 20. Em azul esto os ns da Amrica do Norte, em verde os da Europa, Oriente Mdio, sia Central e frica, e em amarelo os da Amrica Latina.

Todo esse arranjo envolvendo satlites de telecomunicaes, cabos submarinos, redes com e sem fios, fibras ticas, computadores, telefones celulares, circuitos integrados, incrivelmente, tudo isso funciona, com algumas falhas, verdade, mas que no impediram a computao de mudar a forma de vida da humanidade. Funciona como? Essa proeza de organizao se deve exatamente ao uso intenso de uma idia central para a computao, a modularizao. So muitas e muitas peas que compem os computadores do mundo e suas redes, mas que so desenvolvidas de forma a permitir que, para utilizar um mdulo, seja preciso saber apenas o que esse mdulo faz, e no como ele realiza a sua funo. Mdulos permitem a diviso de competncias. Um programador profissional normalmente no tem a menor idia sobre a fsica de semicondutores dos chips, e uma vaga idia de como funcionam internamente os protocolos da Internet. Toda a computao um imenso lego, onde cada pea tem encaixes bem definidos que permitem seu acoplamento para a montagem de estruturas maiores. Veremos ao longo desse curso, que mdulos so onipresentes na cincia da computao, pois so fundamentais para o domnio de sistemas complexos.

1.2 Informao Analgica e Digital


Computadores trabalham com informao, e por isso que a palavra informtica sinnimo de cincia da computao. Informao um conceito de difcil definio; algo em um objeto o objeto suporte que diz alguma coisa sobre outro objeto o objeto alvo que pode ser uma grandeza fsica, ou um evento localizado no tempo, ou qualquer aspecto de interesse no objeto alvo. Quando a maneira de registro da informao no meio suporte tem uma relao fsica direta com o alvo da informao, como a deformao produzida em uma mola por um peso, ns dizemos que a informao ali armazenada informao analgica. Quando o objeto suporte armazena smbolos como nmeros ou palavras com informao sobre o objeto alvo, ns dizemos que a informao simblica ou, mais comumente, informao digital.

20

Barret Lyon, The Opte Project, acessado 7 de maro de 2011, http://opte.org/.

Computadores e Informao

19

Figura 10: Negativos fotogrficos 21

Um filme fotogrfico revelado objeto em extino nos dias de hoje registra informao sobre a cena fotografada. Uma cena, fotografada com uma mquina tradicional, gera informao analgica sobre o material foto-sensvel que cobre o filme. A mesma cena, fotografada com uma mquina digital, gera nmeros que registram a intensidade de luz para cada um de muitos pontos pequeninos que compem a imagem, nmeros que so smbolos, ou seja, so informao digital.

Figura 11: Informao analgica e digital

Um termmetro caseiro um objeto que fornece informao sobre a temperatura do ar, ou do corpo de uma pessoa, pois fenmenos de dilatao fazem com que a altura da coluna de mercrio seja proporcional temperatura medida. Ns dizemos que a informao obtida por um exame direto do termmetro uma informao analgica.

21

Photographic film image, acessado 7 de maro de 2011, http://farm4.static.flickr.com/3444/3348244651_fef16ef641.jpg.

Computadores e Informao

20

Ponto de ebulio da gua

Corpo humano Ponto de fuso do gelo

Figura 12: Um termmetro

Com o uso de uma escala, um mdico pode anotar em um papel a temperatura de seu paciente. Ao faz-lo, a informao sobre a temperatura passa de analgica (a altura da coluna de mercrio) para informao digital ou simblica (os nmeros anotados pelo mdico).

Ponto de ebulio da gua

Corpo humano

Ponto de fuso do gelo

Figura 13: Um termmetro com escala

Existem perdas nessa transformao. O mdico ir anotar o nmero correspondente ao tracinho mais prximo extremidade da coluna, talvez com uma aproximao entre valores de dois tracinhos, mas no a sua altura exata. Para o mdico essa perda pode ser perfeitamente tolervel; temperaturas do corpo humano medidas com uma casa decimal provavelmente atendem a todas as necessidades clnicas. Mas existe tambm um grande ganho: a temperatura anotada informao simblica, que pode ser comunicada por telefone, ou copiada em outro papel, ou digitada em um computador.

Computadores e Informao

21

Ponto de ebulio da gua

50

Corpo humano
50

Ponto de fuso do gelo

Figura 14: Termmetro com escalas Celsius e Farenheit

O uso de informao simblica requer convenes de interpretao. A qual temperatura a qual altura da coluna de mercrio corresponde o smbolo 50? A Figura 14 mostra escalas comumente utilizadas para temperaturas. Ou seja, ao dizer 50 graus, devemos esclarecer se estamos falando de graus centgrados, ou graus Farenheit, ou de alguma outra escala de temperaturas.
Tabela 1: Diferentes smbolos para os nmeros inteiros de 1 a 7

Arbico 1 2 3 4 5 6 7

Romano I II III IV V VI VII

Binrio 1 10 11 100 101 110 111

Smbolos podem tambm ser usados para representar outros smbolos. Assim como explicitar uma escala um requisito para se interpretar um nmero associado a uma temperatura, a correspondncia entre smbolos deve ser estabelecida por convenes, como mostra o exemplo na Tabela 1.

1.3 Computadores e Informao


Computadores so essencialmente formados por processadores, memrias, sensores e atuadores: O componente mais importante o processador. Um processador transforma informao exclusivamente simblica, em informao tambm simblica; as transformaes que um processador realiza so ditadas por um programa que o processador executa. Memrias servem para registrar informaes para recuperao posterior, e tambm s trabalham com informaes simblicas. Sensores como o teclado do computador, o mouse, cmeras e microfones digitais, entradas de rede, telas sensveis ao toque, so tambm chamados de dispositivos de entrada, e trazem informao para o processador.

Computadores e Informao

22

Atuadores so impressoras, monitores de vdeo, alto-falantes, projetores, sadas de rede, e so tambm chamados de dispositivos de sada. Atuadores exportam informao que sai do processador. Sensores e atuadores frequentemente trabalham tanto com informao digital como com informao analgica, e fazem uso de converses A/D e D/A.

A informao digital nos processadores e memrias atuais utiliza somente dois smbolos. A palavra bit designa a unidade de informao simblica; os dois valores possveis para um bit so normalmente denotados por 0 e 1. Dois smbolos s? Computadores fazem maravilhas: exibem filmes, ajudam a projetar automveis, controlam metrs e avies, oferecem jogos, editores de texto, correio eletrnico, fazem de tudo. Como, somente com 0 e 1? que, mesmo se cada bit s contm um de dois smbolos, computadores usam muitos bits. Com 1 bit podemos representar dois estados, que podem por conveno representar 0 ou 1, sim ou no, verdadeiro ou falso, preto ou branco, verde ou amarelo, o que quer que se convencione, mas apenas dois estados. Com dois bits j so 4 combinaes: 00, 01, 10 e 11. Com 3 bits, 8 combinaes: 000, 001, 010, 011, 100, 101, 110 e 111. J fica possvel armazenar 8 diferentes informaes, que poderiam ser os inteiros de 0 a 7, ou os inteiros entre -3 e 4, as letras entre A e H, ou talvez 8 diferentes nveis de cinza: o preto, o branco, e 6 nuanas intermedirias. No difcil ver que, ao acrescentar um bit a um conjunto de bits, multiplicamos por 2 o nmero de combinaes j existentes. Ou seja, com 1 bit, 2 estados; com 2 bits, 2 2 = 4 estados; com 3 bits, 2 4 = 8 estados. Generalizando, com bits, temos 2 combinaes, e 2 cresce muito rapidamente quando o valor de aumenta: Um conjunto de 8 bits chamado de byte. Com 8 bits podemos representar 28 = 256 coisas diferentes. Isso suficiente para atribuir um cdigo distinto para cada letra do alfabeto, distinguindo entre maisculas e minsculas, e tambm para caracteres especiais como (, +, etc. Com 24 bits, temos 224 = 16.777.216 possibilidades, o suficiente para representar todas as cores com qualidade excelente para a acuidade visual humana. Com 80 bits, nada menos que 280 = 1.208.925.819.614.629.174.706.176 coisas podem ser representadas!

A Tabela 2 mostra os prefixos usados para designar potncias decimais e binrias de uso corrente na computao.
Tabela 2: Prefixos binrios e decimais.
Prefixo kilo mega giga tera peta exa zetta yotta Smbolo k/K M G T P E Z Y Prefixos Binrios e Decimais Valor Base 10 210 = 1 024 > 103 = 1,000 220 = 1 048 576 > 106 = 1 000 000 230 = 1 073 741 824 > 109 = 1 000 000 000 40 2 = 1 099 511 627 776 > 1012 = 1 000 000 000 000 250 = 1 125 899 906 842 624 > 1015 = 1 000 000 000 000 000 260 = 1 152 921 504 606 846 976 > 1018 = 1 000 000 000 000 000 000 70 2 = 1 180 591 620 717 411 303 424 > 1021 = 1 000 000 000 000 000 000 000 280 = 1 208 925 819 614 629 174 706 176 > 1024 = 1 000 000 000 000 000 000 000 000

Podemos ver que o uso de apenas 2 smbolos no traz limitao alguma de representatividade. Tudo bem, mas porque s 2 smbolos? Se os projetistas de computadores tivessem sido menos mesquinhos e usassem, por exemplo, os algarismos decimais como unidade bsica de informao, no teramos um sistema que, antes de qualquer coisa, seria familiar, e que com algarismos poderamos representar 10 coisas diferentes? A deciso de adoo de um sistema binrio foi tomada pelos projetistas dos primeiros computadores, e se justifica principalmente pela confiabilidade. Computadores so

Computadores e Informao equipamentos eletrnicos, onde smbolos devem ser representados por voltagens ou correntes eltricas, ou por outras grandezas fsicas. Se tivermos apenas dois nveis de voltagens ou de correntes, a distino dos smbolos fica muito mais confivel.

23

Bits so baratos, e ocupam muito pouco espao quando anotados em suportes eletrnicos. O notebook utilizado para escrever este texto em 2012 tinha 4GB (Giga Bytes) de memria principal, e 300GB de capacidade de armazenamento em sua memria secundria, um disco magntico.

1.4 Converses anlogo-digital e digital-analgica


Existem dispositivos que transformam informao analgica em informao digital (converses A/D), e outros que fazem o contrrio (converses D/A). Muito frequentemente um fenmeno natural usado para converter o fenmeno fsico medido em impulsos eltricos, e estes impulsos so sinais de entrada usados na converso anlogo-digital.

Figura 15: Um microfone converte ondas de presso do ar em impulsos eltricos22

Um exemplo destes dispositivos um microfone, que transforma sons em impulsos eltricos. Como mostra o esquema na Figura 15, as ondas de presso no ar que constituem o som fazem o diafragma vibrar, arrastando consigo um cabo enrolado em solenide. Este cabo se move em um campo magntico, gerando sinais eltricos proporcionais deformao do diafragma. O sinal eltrico produzido pelo microfone pode ento ser acoplado a um dispositivo de converso anlogo-digital. Um alto-falante tem funcionamento similar: um impulso eltrico de entrada aplicado sobre um cabo enrolado em solenoide, o que gera um campo magntico que faz mover uma membrana, que gera ondas de presso no ar que constituem o som emitido.

22

Sound Transducer, acessado 2 de agosto de 2011, http://www.electronics-tutorials.ws/io/io_8.html.

Computadores e Informao

24

Figura 16: Um segundo de um sinal analgico

Para digitalizar um sinal de entrada como o da Figura 16 preciso obter amostras de sua amplitude em instantes discretos no tempo, e digitalizar obter um valor numrico cada amostra.

22=4

Figura 17: Sinal original e amostras, feitas 4 vezes por segundo, com preciso de 2 bits

A Figura 17 ilustra esse processo de digitalizao de um sinal que varia ao longo do tempo. O resultado da digitalizao uma tabela um conjunto de smbolos, com a informao mostrada na Figura 18.

Computadores e Informao
Tempo(s) 0.00
0.33 0.66

25
Sinal(V) 00 (0)
10 (2) 10 (2)

1.00

00 (0)

Figura 18: Resultado da digitalizao com 4 amostras/s e 2 bits de preciso

Aps a digitalizao, a informao analgica perdida, e somente os smbolos resultantes da digitalizao esto disponveis. Para tentar reconstruir o sinal original a partir dos dados digitalizados, um primeiro passo poderia ser utilizar interpolao linear para obter dados intermedirios entre os vazios existentes entre as amostras, como mostra a Figura 19

Figura 19: Reconstruo do sinal por interpolao linear

Se compararmos com o sinal original veremos que, para a nossa acuidade visual, o resultado no nada bom, como mostra a Figura 20.

Figura 20: Sinal original e sinal reconstrudo por interpolao linear a partir de digitalizao com 4 amostras/s e 2 bits de preciso

Se tentarmos reconstruir o sinal com mtodos mais sofisticados de interpolao, como splines (veremos mais tarde como utilizar splines), o resultado tambm no ser bom, como mostra a Figura 21.

Computadores e Informao

26

Figura 21: Sinal original e sinal reconstrudo por interpolao por spline a partir de digitalizao com 4 amostras/s e 2 bits de preciso

Para tentar melhorar a situao, vamos primeiramente aumentar a frequncia de amostragem do sinal para 40 amostras/s, mantendo os 2 bits de preciso. A Figura 22 mostra as amostras obtidas pelo processo de digitalizao, e a Figura 23 sua reconstruo por interpolao linear e spline.

22=4

Figura 22: Sinal original e amostras, feitas 40 vezes por segundo, com preciso de 2 bits

Computadores e Informao

27

Figura 23: Sinal original e sinal reconstrudo por interpolao linear e spline, com 40 amostras/s e 2 bits de preciso

Ns vemos que a reconstruo se aproximou mais do sinal original, mas o resultado ainda no bom. fcil ver que o problema agora est na preciso com que os valores so amostrados, pois com 2 bits s temos 4 possibilidades de atribuio de valores para as amostras.

26=64

Figura 24: Sinal original e amostras, feitas 40 vezes por segundo, com preciso de 6 bits

Se utilizarmos 6 bits de preciso (ou 6 bits de profundidade), teremos 26 = 64 valores possveis para cada amostra, e a qualidade da digitalizao claramente superior, como mostra a Figura 24.

Figura 25: Sinal original e sinal reconstrudo por interpolao linear e spline, com 40 amostras/s e 6 bits de preciso

Computadores e Informao

28

Na reconstruo do sinal, como mostra a Figura 25, os resultados so muito bons com os dois mtodos de interpolao. Portanto, a qualidade da digitalizao depende: da freqncia da amostragem e da preciso com que feita cada amostragem.

Podemos sempre tentar aumentar a o nmero de bits e a freqncia de amostragem, mas isso tem custos. Dependendo da utilizao final do sinal reconstrudo, os custos com a melhoria de qualidade nem sempre so compensatrios. Se considerarmos que o sinal est sendo amostrado para apreciao visual por humanos, a partir de um certo ponto a qualidade da digitalizao atingir os nossos limites de acuidade visual ou sonora. Um CD musical amostrado com frequncia de 44,1 kHz e 16 bits de preciso, o que propicia uma qualidade bastante satisfatria; um sistema de udio sofisticado utiliza amostras com 96 kHz e 24 bits de profundidade, o que satisfaz ouvidos exigentes de msicos profissionais. Como concluso, importante observar que a converso de informao em qualquer dos dois sentidos A/D ou D/A nunca perfeita, mas em muitos casos pode ser to boa quanto se necessite. Em converses D/A (Digital/Analgica) destinadas absoro por humanos, a explorao de limites fisiolgicos como a acuidade visual ou auditiva muito utilizada.

1.5 Sensores e atuadores

Figura 26: Computadores, programas e informao digital

Programas so escritos por pessoas e executados por computadores. Programas so compostos por instrues e comandos que lm, transformam e registram informao digital.

Computadores e Informao

29

Figura 27: Sensores e atuadores

A informao digital recebida pelo computador por sensores (ou equipamentos de entrada) e, normalmente aps alguma transformao, enviada para atuadores (ou equipamentos de sada).

Figura 28: Interao homem-mquina

A interao entre humanos e computadores tambm se d atravs de sensores e atuadores. Presente em quase todos os computadores, o sensor mais comum o teclado. Sua importncia imensa. atravs de teclados que entra, por exemplo, quase toda a informao que movimenta a economia mundial. O teclado pode ser tambm uma barreira pessoal para a entrada no mundo da informtica. (Uma pessoa com dificuldades na digitao tende a abandonar os computadores, em uma atitude que provavelmente lhe trar conseqncias profissionais negativas.)

Figura 29: Barbara Blackburn, recordista mundial de velocidade de digitao 23, e um teclado Dvorak, projetado para maximizar a velocidade de digitao em ingls

Outras pessoas, pelo contrrio, tm grande facilidade para a digitao. O recorde mundial de digitao pertence a Barbara Blackburn, que atingia uma velocidade sustentada de 15 toques por segundo, com picos de 20 toques por segundo, usando um teclado Dvorak (Figura 29).
23

Barbara Blackburn, the Worlds Fastest Typist, acessado 15 de setembro de 2012, http://rcranger.mysite.syr.edu/famhist/blackburn.htm.

Computadores e Informao

30

Estamos nos permitindo essa digresso para calcular a velocidade de produo de informao por um teclado. Considerando que cada toque produz 8 bits (um byte), a Barbara Blackburn produzia informao a uma taxa mxima de 160 bps (bps = bits por segundo).

Figura 30: Uma camcorder de alta definio um sensor que produz bits a uma taxa de 24 Mbps

Uma cmera de vdeo produz bits a taxas muito mais altas. Uma camcorder de alta definio pode gerar 24Mbps, ou 24 milhes de bits por segundo.

Figura 31: Sensores especiais: um rdio-telescpio e um acelerador de partculas

A cincia faz uso de sensores que produzem informao ainda muito mais rapidamente. Rdio-telescpios ou aceleradores de partculas podem produzir informao taxas de Gbps, ou seja, bilhes de bits por segundo, milhes (literalmente) de vezes mais rpido do que o recorde mundial de digitao.

Figura 32: Um atuador especial: um brao mecnico

Atuadores comuns so monitores, impressoras, alto-falantes. Existem tambm atuadores especiais como braos mecnicos usados por robs, como mostrado na Figura 32.

Computadores e Informao

31

Figura 33: Redes de computadores

Entradas e sadas de rede so particularmente importantes pois permitem a conexo entre computadores. Um atuador de um computador emite sinais eltricos, ou de rdio, ou ticos, que so percebidos lidos por um sensor de outro computador.

1.6 Memrias
Memrias tm funo anloga a papel e lpis: so usadas por computadores para registrar informaes para recuperao posterior. Um computador geralmente trabalha com diversos tipos de memria, que seguem uma distribuio hierrquica: Registradores so memrias muito pequenas e muito rpidas, que se encontram dentro do mesmo chip do processador, e que tm suas entradas e sadas ligadas diretamente a circuitos que realizam transformaes de informao, como a unidade aritmtica que, como o nome indica, realiza operaes aritmticas. Memria principal ou RAM (Random Access Memory) um circuito externo ao processador, mas de acesso ainda bastante rpido. Instrues executadas pelo processador utilizam diretamente operandos armazenados na memria principal. Transformaes como operaes aritmticas geralmente exigem que informao seja previamente transferida da memria principal para registradores, onde as operaes so realizadas, e os resultados posteriormente armazenados na memria principal. De uma forma geral a memria principal voltil, no sentido em que necessrio manter o computador ligado para que a informao ali armazenada no se perca. A volatilidade no uma necessidade, mas uma caracterstica da tecnologia empregada nas memrias principais atuais. H alguns anos atrs memrias principais utilizavam ncleos de ferrite, com o registro da informao feito por polarizaes magnticas no volteis.

Computadores e Informao

32

Figura 34: 4GB de RAM montados em um computador pessoal

Figura 35: Memria de ncleos de ferrite24, usada em 1964 pelo supercomputador CDC 6600, com 64 palavras de 64 bits em 11x11 cm

24

Magnetic-core memory - Wikipedia, the free encyclopedia, acessado 12 de maro de 2011, http://en.wikipedia.org/wiki/Magnetic_core_memory.

Computadores e Informao

33

Memrias secundrias so tipicamente discos rgidos, onde informaes tambm podem ser lidas e escritas, mas o processador deve executar instrues especiais de entrada e sada para isso. Memrias flash (memrias usadas em pen drives, no iPod) vm sendo tambm cada vez mais utilizadas como memrias secundrias. Memrias secundrias so no-volteis, com a informao armazenada permanecendo registrada mesmo sem qualquer alimentao de energia. A informao em uma memria secundria quase sempre formatada em arquivos e diretrios, que provm uma abstrao essencial para o seu uso.

Figura 36: Um disco rgido sem a cobertura protetora, mostrando o movimento da cabea de leitura e gravao

Memrias tercirias so necessrias em ambientes maiores, que armazenam grandes volumes de dados. Fitas magnticas so utilizadas, com um rob que capaz de localizar a fita correta em um repositrio e mont-la em uma unidade de fita ligada ao computador.

Computadores e Informao

34

Figura 37: Armazenamento tercirio com uma grande coleo de fitas magnticas manipuladas por um brao robtico25

Na Figura 38 ns vemos uma forma de se escrever os smbolos 0 e 1 em um meio magntico, atravs de sequncias de reverses ou no reverses de polarizao de pequenas regies gravadas em discos ou fitas.

Figura 38: Escrevendo zeros e uns em meio magntico26

25

NCARs MSS exceeds 2 petabytes, acessado 12 de agosto de 2011, http://www.cisl.ucar.edu/news/04/fotoweek/0729.mss2pb.html. 26 File:MagneticMedia.png - Wikipedia, the free encyclopedia, acessado 12 de agosto de 2011, http://en.wikipedia.org/wiki/File:MagneticMedia.png.

Computadores e Informao

35

1.7 Organizao do Contedo


Este material destina-se a disciplinas introdutrias de organizao e programao de computadores para alunos de cincias e de engenharia, e tem como objetivos: introduzir noes bsicas de circuitos digitais, organizao de computadores, representao de dados e programao, apresentar ao aluno alguns princpios bsicos da construo e da anlise de algoritmos mtodos computacionais para transformao de informao e de sua implementao em um ambiente de programao, e tornar o aluno fluente no uso de uma ferramenta computacional, o Scilab, de vasta aplicao nas cincias e engenharias.

O material est dividido em trs partes: Parte I: Organizao de Computadores Parte II: Ambiente e Linguagem Scilab Parte III: Algoritmos e Programas

A Parte I, Organizao de Computadores, tem dois objetivos principais: dar ao aluno uma compreenso dos elementos essenciais do funcionamento interno de um computador, e permitir ao aluno perceber a dificuldade da programao em baixo nvel, e apreciar os ganhos obtidos com o uso de compiladores e interpretadores

A interpretao de conjuntos de bits estabelecida por convenes de cdigos que associam a uma determinada configurao de bits um valor numrico, ou um nvel de vermelho em uma imagem, ou o que quer que se convencione. So apresentados alguns dos cdigos mais comumente utilizados na computao. Circuitos combinatrios, isto , circuitos digitais que realizam transformaes sobre um conjunto de bits de entrada produzindo outro conjunto de bits como sada, no tm memria, e sua sada em um dado instante funo apenas dos valores de entrada nesse instante. Circuitos combinatrios utilizam portas lgicas, que so componentes que realizam as operaes AND, OR e NOT que constituem a lgebra de Boole. So vistos circuitos combinatrios para somas, comparaes e para direcionamento de fluxo de dados.

Figura 39: Circuito combinatrio, simulado no Logisim, que realiza a soma de duas parcelas binrias de 4 bits

Computadores e Informao

36

Circuitos seqenciais tm a sua sada influenciada tambm pelo valor corrente de suas memrias. O elemento bsico de memria o flip-flop, capaz de armazenar um bit. Conjuntos de flip-flops formam registradores, que so ligados a outros registradores e a circuitos combinatrios por meio de barramentos. So tambm introduzidos circuitos de memrias onde ficam armazenados dados e programas. Osciladores e registradores circulares so introduzidos como elementos para controle da evoluo temporal de um circuito.

Figura 40: Circuito sequencial, simulado no Logisim, que acumula a soma das entradas.

A primeira parte culmina com a apresentao de processadores, que so circuitos que transformam informao de forma flexvel, determinada por um programa que carregado em uma memria, e que pode ser substitudo com facilidade. O estudo da organizao de computadores ter permitido ao aluno tanto conhecer melhor o funcionamento bsico de um computador, como ter um contato com as dificuldades da programao a nvel de instrues de mquina de um computador. A Parte II, Linguagem e Ambiente Scilab, tem como objetivos principais: a introduo de uma linguagem de alto nvel, Scilab (Scilab Consortium, s.d.), que facilita imensamente a tarefa de programao de computadores atravs da oferta de comandos com formato muito mais prximo da forma como seres humanos raciocinam, e a familiarizao do aluno com o ambiente de desenvolvimento e de execuo de programas fornecido pelo Scilab.

Inicialmente apresentado o Scilab como uma linguagem de alto nvel, com variveis, expresses aritmticas e comandos de atribuio. So vistas variveis que contm valores numricos, lgicos ou cadeias de caracteres. Em seguida so apresentadas construes de linguagem para expressar comportamentos condicionais e repetitivos. Matrizes constituem o ponto forte do Scilab. Ns veremos como criar e modificar matrizes, realizar operaes de aritmtica matricial, como construir matrizes a partir de matrizes j existentes, e uma srie de outras operaes. Um uso freqente de matrizes no Scilab para a construo de grficos, feita por comandos muito flexveis. Em seguida so vistos comandos para a manipulao de arquivos, que so conjuntos de dados que tipicamente so produzidos por um programa e armazenados em um disco rgido ou um pen drive, e lidos posteriormente por outro programa. Arquivos so absolutamente essenciais para o tratamento de grandes volumes de dados.

Computadores e Informao A Parte II se encerra com o estudo de funes Scilab, que constituem uma ferramenta essencial para o uso de mdulos na construo de programas.

37

Para exemplificar o uso do Scilab para a construo de programas, consideremos o seguinte problema. Temos um arquivo ondas.txt (fonte: (StatLib, 1989) )que contm dados obtidos em um laboratrio de observao de ondas marinhas (Figura 41).

Figura 41: O arquivo ondas1.txt visto com o Bloco de Notas

Cada linha do arquivo contm uma medida do nvel do mar; a aparelhagem do laboratrio permite fazer 30 medidas por segundo. O arquivo completo tem 4096 linhas. Ns queremos um programa para obter um grfico com os pontos do arquivo, e tambm saber os valores mximo e mnimo presentes na amostra.

Computadores e Informao

38

// Programa da Onda getf("Minimo.sci"); Leitura do arquivo getf("Maximo.sci"); arq = xgetfile(); Gerao do grfico Onda = fscanfMat(arq); Sada plot2d(Onda); printf("Min = %5.2f, Max = %5.2f",... Minimo(Onda), Maximo(Onda));

Funes utilizadas

Figura 42: O programa Scilab Onda.sci. Cada linha um comando, a no ser que termine em .... Linhas que se iniciam com // so comentrios que se destinam a leitores humanos.

A Figura 42 mostra um programa Scilab que faz isso, utilizando dois mdulos, as funes Maximo e Minimo, mostradas na Figura 43.

Figura 43: As funes Maximo e Minimo vistas no editor SciNotes

Para entender melhor essas funes, veja o algoritmo descrito a seguir nesta seo. O programa produz o grfico da Figura 44, e a sada Min = -0.86, Max = 0.36 mostrada na console do Scilab.

Computadores e Informao

39

Figura 44: Grfico com os pontos no arquivo ondas1.txt

Na parte III, Algoritmos, nosso foco se afasta um pouco de especificidades da linguagem Scilab para abordar aspectos da programao de computadores que so independentes da linguagem utilizada. Ns continuamos a usar o Scilab, mas o contedo dessa parte seria essencialmente o mesmo se estivssemos utilizando C, Java, Fortran ou qualquer outra linguagem. Ns veremos que um algoritmo um mtodo para transformao de informao de entrada em informao de sada, e que em boa parte independente da linguagem particular em que est descrito. A transformao desejada definida por uma especificao que resulta de uma anlise de um problema.

A = [39. 24. 50. 42. 28. 8. 62. 34. 70.

52.];

Figura 45: Como encontrar o menor valor em uma coleo de nmeros?

Como um exemplo, queremos encontrar o menor valor presente em uma coleo de nmeros. Com 10 nmeros, como mostrados na Figura 45, fcil; podemos faz-lo por inspeo visual. Mas como encontrar o menor valor entre, digamos, 50.000 nmeros? Para isso precisamos de um algoritmo, isto , de um mtodo que tenha como informao de entrada a coleo de nmeros, e como sada o menor valor ali presente. Em programao uma coleo de nmeros chamada vetor. O primeiro elemento de um vetor notado (1); o quinto, (5); o -simo, (). Queremos portanto construir um algoritmo que encontre o menor valor em um vetor de tamanho arbitrrio. Para isso, vamos comear com o caso mais simples possvel: um vetor com um nico elemento, que obviamente o menor elemento presente no vetor. Tudo bem, mas queremos trabalhar com vetores grandes de verdade. Para avanar, usamos induo. Suponhamos que, de alguma forma, descobrimos que o menor valor entre os primeiros elementos de um vetor de tamanho . Podemos ento inferir que o menor valor entre os + 1 primeiros elementos de o menor entre e ( + 1). Como j sabemos encontrar o mnimo em um vetor de 1 elemento ( = 1), sabemos encontrar o mnimo em um vetor com 2 elementos; como sabemos encontrar o mnimo em um vetor de 2 elementos, sabemos encontrar o mnimo em um vetor com 3 elementos.

Computadores e Informao Prosseguindo com o raciocnio, j temos um algoritmo para encontrar o menor valor em um vetor de tamanho arbitrrio. Tendo um algoritmo, no temos mais medo do problema com 50.000 nmeros. Nosso trabalho ser programar o algoritmo; caber ao computador a sua execuo.
A = [39.

40

24. 24.

50. 50.

42. 42.

28. 28.

8. 8.

62. 62.

34. 34.

70. 70.

52.]; 52.];

A = [39.

A = [39.

24. 24.
24.

50. 50.
50.

42. 42.
42.

28. 28.
28.

8. 8.
8.

62. 62.
62.

34. 34.
34.

70. 70.
70.

52.]; 52.];
52.];

A = [39. A = [39.

A = [39.

24.

50.

42.

28.

8.

62.

34.

70.

52.];

Figura 46: Seis primeiros passos do algoritmo que encontra o menor valor presente em um vetor

Um algoritmo dito correto quando atende sua especificao. Dois algoritmos corretos podem satisfazer uma mesma especificao, mas diferir substancialmente na eficincia (gasto de tempo e de recursos computacionais como memria) com que realizam a transformao de informao desejada. O termo complexidade empregado para designar a eficincia (ou melhor, o inverso da eficincia) de um algoritmo para a soluo de um problema. A complexidade de algoritmos estudada inicialmente com dois problemas clssicos da cincia da computao: a ordenao dos elementos de um vetor e a busca por um elemento de um vetor com valor igual a uma chave dada. Para cada um desses problemas so vistos algoritmos que diferem em sua complexidade. Encontrar uma raiz de uma funo ou resolver um sistema de equaes lineares so exemplos de problemas numricos que um cientista ou engenheiro frequentemente tem que resolver. Ns veremos alguns exemplos de algoritmos que resolvem problemas desse tipo, e tambm alguns cuidados que devem ser tomados ao se desenvolver programas para estas aplicaes. Algoritmos com melhor complexidade so fruto de engenho e arte de seus projetistas. Existem entretanto problemas cuja soluo algortmica intrinsecamente difcil, no sentido em que no existem boas solues para eles. A Parte III e o curso se encerram com exemplos de problemas computacionalmente difceis, e de problemas para os quais simplesmente no existe nenhum algoritmo que os resolvam para todos os casos.

Circuitos Combinatrios

42

2 Circuitos Combinatrios
Computadores transformam informao de entrada em informao de sada. Entradas e sadas podem lidar com informao analgica, mas um processador, o principal componente dos computadores, transforma informao exclusivamente simblica de entrada em informao simblica de sada. Isto feito por composies de transformaes bsicas extremamente simples sobre os smbolos 0 e 1. Neste mdulo ns veremos quais so essas transformaes bsicas e como essas transformaes bsicas so implantadas com transistores, o que permite a sua implementao em semicondutores com dimenses fsicas muito reduzidas. Veremos tambm como combinar essas transformaes para obter circuitos que realizam a soma ou a comparao de dois nmeros, ou o estabelecimento de conexes flexveis, guiadas por informaes de endereo, para o transporte de informao em um circuito lgico.

2.1 Bits e cdigos


Para ter utilidade, informao simblica exige convenes de interpretao. Qualquer pessoa pode dar a um conjunto de bits a interpretao que bem entender, e programadores com freqncia escolhem codificaes que atendem s suas prprias necessidades, sem outras preocupaes. Mas quando se quer enviar ou receber dados de outras pessoas, ou utilizar circuitos j construdos para a realizao de operaes aritmticas, a escolha de um cdigo com maior aceitao praticamente uma imposio. Ns veremos a seguir alguns dos cdigos mais utilizados em computao. ASCII e UNICODE. Para a comunicao com humanos a linguagem escrita essencial. Seres humanos lm e escrevem usando algum alfabeto, algarismos, smbolos de pontuao, e esta uma parte essencial de nossa comunicao. O cdigo ASCII American Standard Code for Information Interchange uma dessas convenes de ampla aceitao em toda a indstria da computao, e que tem como objetivo a codificao de smbolos teis, chamados caracteres, para a comunicao por escrito com humanos.

Caractere End of Transmission Line Feed Space ( + 0 1 2 3 A B C a b c

Cdigo 0000100 0001010 0100000 0101000 0101011 0110000 0110001 0110010 0110011 1000001 1000010 1000011 1100001 1100010 1100011

Decimal 4 10 32 40 43 48 49 50 51 65 66 67 97 98 99

Figura 47: Exemplos de codificao ASCII

Circuitos Combinatrios

43

A Figura 47 mostra partes do cdigo ASCII, cuja primeira verso foi proposta em 196327. O cdigo foi projetado para a representao de caracteres como A, a, (, +, etc., para o espao em branco (sim, o espao tambm exige uma representao), e para os chamados caracteres de controle, como line feed, para indicar uma troca de linhas. O cdigo ASCII oficial usa 7 bits, o que permite 27 = 128 combinaes. Destas, 33 representam caracteres de controle como Line Feed ou Carriage Return, muito teis, especialmente nos tempos em que teletipos mquinas de escrever comandadas por computador eram um perifrico essencial para os operadores.

Figura 48: Dennis Ritchie (em p) e Ken Thompson, fotografados durante o desenvolvimento do sistema operacional Unix (o Linux uma verso do Unix, (re)escrita por Linus Torvalds) e da linguagem C, usando um teletipo como terminal de um PDP-11, em 197228

Tendo sido proposto por norte-americanos no incio da era dos computadores, no de se estranhar que no cdigo ASCII no haja proviso para caracteres acentuados ou cedilhas. Estes so contemplados no cdigo ASCII estendido, que usa 8 bits (um byte) para representar 256 caracteres. O sucessor moderno do cdigo ASCII o Unicode29, um padro de codificao capaz de representar caracteres chineses, rabes, tailandeses, enfim, de praticamente qualquer conjunto de caracteres das lnguas vivas e mortas do mundo. Unicode permite diversas codificaes em bits. A codificao mais importante a mais utilizada na Internet a UTF-8, que utiliza entre 1 e 4 bytes para a representao de caracteres. Os caracteres representados
27

ASCII - Wikipedia, the free encyclopedia, acessado 18 de agosto de 2011, http://en.wikipedia.org/wiki/ASCII. 28 Ken&Den picture, acessado 24 de setembro de 2012, http://cm.belllabs.com/cm/cs/who/dmr/picture.html. 29 Unicode - Wikipedia, the free encyclopedia, acessado 19 de agosto de 2011, http://en.wikipedia.org/wiki/Unicode.

Circuitos Combinatrios por um nico byte tm a mesma representao em UTF-8 e em ASCII, uma compatibilidade essencial para o bom funcionamento de programas que contavam com codificao ASCII.

44

Binrios sem Sinal. Um outro critrio para a escolha de um cdigo a sua adequao para operaes aritmticas. No cdigo ASCII estendido o nmero decimal 123 pode ser representado pela seqncia de 24 bits 00110001 00110010 00110011 (colocamos espaos para facilitar a leitura). Esta uma codificao muito boa para a impresso de nmeros por dispositivos que permitem leitura por humanos, e tambm para a codificao da entrada produzida por teclados. Mas para operaes aritmticas, a interpretao de um conjunto de bits como um nmero em notao posicional na base 2 leva a cdigos mais compactos e que, como veremos, permitem a realizao de operaes de soma por circuitos mais simples, mais rpidos e mais baratos.

n 2n

0 1

1 2

2 4

3 8

4 16

5 32

6 64

7 128

8 256

9 512

10 1024

Figura 49: Tabela com potncias de 2

O decimal 123 pode ser representado em binrio por 1111011, utilizando apenas 7 bits. Esta representao vem do fato que 123 = 1. 26 + 1. 25 + 1. 24 + 1. 23 + 0. 22 + 1. 21 + 1. 20 .

Decimal Binrio

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111
Figura 50: Representao dos nmeros de 0 a 15 como binrios sem sinal de 4 bits

A converso de 12310 para 11110112 pode ser feita com o seguinte mtodo para converso binrio-decimal: Ns precisamos expressar 123 como uma soma de potncias de 2. Para isso, procuramos em uma tabela de potncias de 2 (como a tabela na Figura 49, mas talvez maior, pois a tabela deve chegar at uma potncia de 2 maior que o nmero a ser convertido) o maior valor que no exceda 123 o que, no caso, 64. Temos 123 = 64 + (123 64) = 64 + 59. Temos agora que expressar 59 como uma soma de potncias de 2. Na tabela da Figura 49, a maior potncia de 2 que no excede 59 32. Repetindo o raciocnio, temos 59 = 32 + (59 32) = 32 + 27.

Desta forma progredimos at que a parcela restante a converter como soma de potncias de 2 seja igual a zero.
A converter Potncia de 2 123 64 59 32 27 16 11 8 3 2 1 1 0

Figura 51: Converso do decimal 123 para binrio

Um uso comum de nmeros representados como binrios sem sinal o sistema RGB (Red, Green, Blue) para a codificao da cor associada a um pixel um ponto em um monitor com os valores dos nveis de intensidade das cores primrias componentes vermelho, verde e azul. Para cada uma dessas cores utiliza-se um byte (8 bits), o que permite representar nveis de intensidade entre 0 e 255. Essa preciso considerada satisfatria para a nossa acuidade visual.

Circuitos Combinatrios

45

Figura 52: Uso de binrios sem sinal para a representao dos nveis de intensidade das cores primrias vermelho (Red), verde (Green) e azul (Blue), conhecido como RGB

Sinal e Magnitude. Como computadores s usam bits, ns no podemos usar um sinal - para indicar que um valor negativo. Temos que usar bits para codificar essa informao. A codificao para nmeros negativos conhecida como sinal e magnitude bastante natural. Basta tomar o bit mais esquerda e interpret-lo como o sinal do nmero: se for 0, o nmero cuja amplitude representada pelos bits restantes positivo, e se for 1, negativo. Portanto, se tivermos 8 bits, o bit mais esquerda ser usado para codificar o sinal. Os 7 bits restantes nos permitem representar amplitudes entre 0 e 127, ou seja, podemos, com os 8 bits, representar os inteiros entre -127 e +127. Repare que zero tem duas representaes: 10000000 e 00000000. Codificao com Deslocamento. Uma outra possibilidade para representar nmeros negativos est ilustrada na Figura 53. A conveno adotada de interpretar um conjunto de bits como a representao de um valor igual ao valor de sua interpretao como binrio sem sinal, deslocado por um fator a ser subtrado.
Decimal 0 1 2 3 4 5 6 7 Binrio 000 001 010 011 100 101 110 111 Nmero -3 -2 -1 0 1 2 3 4

Figura 53: Representao de nmeros negativos por deslocamento

Complemento de 2. A absoluta maioria dos computadores utiliza uma codificao conhecida como complemento de 2 para a representao de nmeros inteiros negativos. A Figura 54 mostra a codificao em 3 bits dos inteiros entre -4 e 3 usando complemento de 2.

Circuitos Combinatrios
Complemento de 2 Bits b1 b0 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1

46

b2 0 0 0 0 1 1 1 1

Valor 0 1 2 3 -4 -3 -2 -1

Figura 54: Codificao em complemento de 2 com 3 bits

O valor representado pela sequncia de bits 2 1 0 dado pela frmula = 42 + 21 + 0 . (Ns adotaremos neste texto a conveno de designar sempre por 0 o bit menos significativo e por o bit mais significativo de uma sequncia de bits.) O valor representado por 101 , portanto, dado por = 4.1 + 2.0 + 1.1 = 3. Voc pode estar se perguntando como que algum pode preferir usar complemento de 2, sendo que as propostas anteriores so muito mais simples e intuitivas. A motivao simples, e decisiva para todos os fabricantes de computadores: custo. A representao em complemento de 2 tem propriedades que permitem uma grande economia na construo de circuitos. Para se obter o negativo de um nmero, basta complement-lo bit a bit, e somar 1. Por exemplo, 2 representado por 010; complementando bit a bit, obtemos 101; somando 1, chegamos a 110, que a representao de -2. Ao inverter todos os bits de 000, obtemos 111; somando 1, obtemos 1000, caso em que s os trs bits menos significativos devem ser aproveitados. Isso permite aos fabricantes aproveitar para fazer subtraes usando o mesmo circuito utilizado para fazer somas, com acrscimos mnimos de hardware. Ponto Flutuante. A representao em um nmero limitado de bits de valores muito grandes ou muito pequenos utiliza mecanismos para sua codificao similares aos que usamos na notao cientfica com potncias de 10. O nmero de Avogadro, por exemplo, notado por 6,02 1023 , e o dimetro de um tomo de hidrognio de 1,0 108 metros. Para o nmero de Avogadro ns dizemos que a mantissa ou significando 6,02 e o expoente, 23. Este mesmo nmero poderia ser escrito como 602 1021 , ou como 0,000602 1027 , mas costume adotar a forma normalizada, isto , com um nico algarismo no nulo antes da vrgula. A codificao de nmeros em ponto flutuante atribui a alguns dos bits do nmero o significado de um expoente no de 10 mas de 2. Existe um padro para ponto flutuante de aceitao total pela indstria que o IEEE 754. Para nmeros de preciso simples, o IEEE 754 utiliza 32 bits, sendo 1 bit para o sinal (0 = positivo, 1 = negativo), 8 para o expoente e 23 para a mantissa. Para preciso dupla so 64 bits: 1 para o sinal, 11 para o expoente e 52 para a mantissa. A codificao por deslocamento que acabamos de ver utilizada para permitir a representao de expoentes negativos. Para nmero de 32 bits, o deslocamento do expoente de 127; para nmeros de 64 bits, de 1023. A mantissa normalizada, isto , tem um nico algarismo no nulo antes da vrgula que, como sempre igual a 1 no sistema binrio, no necessita ser representado.

Circuitos Combinatrios

47

Significando
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

0 1 0 0 1 1 1 1 1 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

A Figura 55 mostra um nmero em ponto flutuante de 32 bits. Voc deve reparar que os bits do expoente codificam 159, se interpretados como um binrio sem sinal; com o deslocamento, o expoente de 2 igual a 159 127 = 32. O nmero ali codificado portanto igual a (1)0 (1 + 21 + 23 + 25 ) 232 = 1,65625 232 = 7113539584 O padro IEEE 754 define interpretaes especiais para expoentes s com 1s e s com 0s, incluindo o prprio zero (com expoente e mantissa iguais a zero), valores especiais como ou NAN (Not A Number), que so utilizados para a comunicao de resultados de certas operaes ou do clculo de algumas funes. A referncia 30 tem um bom resumo do padro IEEE 754.

2.2 lgebra de Boole


Em 1854 o matemtico ingls George Boole props uma lgebra para o clculo da validade de expresses formadas por proposies lgicas31. Quase um sculo depois, Claude Shannon32, ento com 21 anos, em sua dissertao de mestrado defendida no MIT em 1937, demonstrou que o projeto de circuitos lgicos, que viriam a constituir a base dos computadores, poderia se beneficiar diretamente destes resultados. Shannon tinha tomado conhecimento dos trabalhos de Boole em um curso de filosofia. Essa lgebra chamada hoje de lgebra de Boole, e constitui a base para o projeto de circuitos digitais. Ela trabalha com variveis lgicas, isto , com variveis que podem ter somente os valores verdadeiro ou falso, ou 1 ou 0.

30

Steve Hollasch, IEEE Standard 754 Floating-Point, acessado 7 de maro de 2011, http://steve.hollasch.net/cgindex/coding/ieeefloat.html.
31

An investigation of the laws of thought [microform]: on which are founded the mathematical theories of logic and probabilities: Boole, George, 1815-1864: Free Download & Streaming: Internet Archive, acessado 19 de agosto de 2011, http://www.archive.org/details/investigationofl00boolrich. 32 Claude Shannon - Wikipedia, the free encyclopedia, acessado 19 de agosto de 2011, http://en.wikipedia.org/wiki/Claude_Shannon.

128 0 0 16 8 4 2 1 0,5 0 0,125 0 0,03125 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0


159 32 7113539584 1,65625

Expoente

Valor

Figura 55: Um nmero em ponto flutuante com 32 bits

Circuitos Combinatrios

48

Figura 56: George Boole, 1820-189833, e Claude Shannon, 1916-200134

As operaes fundamentais da lgebra de Boole so NO, E e OU, mais conhecidas pelas palavras em ingls NOT, AND e OR. Essas operaes fundamentais, ou melhor, composies dessas operaes fundamentais constituem as nicas transformaes feitas por qualquer computador sobre bits.

a 0 1

NOT a 1 0

a 0 0 1 1

b 0 1 0 1

a OR b 0 1 1 1

a 0 0 1 1

b 0 1 0 1

a AND b 0 0 0 1

Figura 57: Definio das operaes NOT, OR e AND

A Figura 57 mostra as definies dessas operaes. O que se v nas tabelas bastante intuitivo: A operao de negao (NOT) uma funo de um nico argumento, e simplesmente inverte o valor de entrada; A operao OR uma funo de 2 argumentos, e tem como resultado 1 se pelo menos uma das entradas for igual a 1, e s igual a 0 quando todas as entradas forem iguais a 0; Inversamente, a operao AND tem 0 como resultado se qualquer uma das entradas for igual a 0, e s igual a 1 quando todas as entradas forem iguais a 1.

Expresses booleanas ou expresses lgicas so composies dessas operaes bsicas, geralmente escritas utilizando uma notao mais compacta:
33

denota NOT

George Boole - Wikipedia, the free encyclopedia, acessado 23 de fevereiro de 2012, http://en.wikipedia.org/wiki/George_Boole. 34 Claude Shannon - Wikipedia, the free encyclopedia.

Circuitos Combinatrios + denota OR . ou denota AND

49

Parnteses so usados em expresses booleanas da mesma forma que usamos em expresses aritmticas. Exemplos de expresses booleanas so + e ( + ).

Porta NOT Porta AND

Porta OR Entrada Sada

Figura 58: Portas lgicas, entradas e sadas em um diagrama de circuito

Circuitos digitais que implementam operaes booleanas so conhecidos como portas lgicas. A Figura 58 mostra um diagrama de circuito contendo desenhos adotados por conveno para entradas, sadas e portas NOT, AND e OR e suas conexes. Na lgebra de Boole diversas expresses so equivalentes; por exemplo, ( ) = ; + = ; . = + 1 = 1; + 0 = . 1 = ; . 0 = 0 + ( + ) = ( + ) + = + + . + . = Voc pode demonstrar as propriedades acima simplesmente calculando as expresses para todos os valores possveis para as variveis envolvidas. Duas expresses equivalentes podem levar a circuitos equivalentes funcionalmente, mas com custos e desempenho distintos, como mostra a Figura 59. A simplificao de expresses booleanas portanto uma rea da mais alta importncia, mas que foge do nosso escopo.

Circuitos Combinatrios

50

Figura 59: Dois circuitos funcionalmente equivalentes

Repare na conveno utilizada nos diagramas de circuito. Dois fios que se cruzam esto em contato eltrico somente se sua interseo for uma bolinha; sem esta bolinha, os fios se cruzam no desenho,mas no esto em contato.

2.3 Portas Lgicas e Transistores


Portas lgicas podem ser implantadas usando transistores, que so a base para a construo de circuitos compactos e rpidos. Por um lado, a tecnologia de 2011 permite colocar 2,6 bilhes de transistores em um chip de 1,6 mm de lado, e por outro, o tempo de reao de um desses transistores a mudanas em suas entradas muito pequeno, da ordem de nanosegundos (109 segundos) ou mesmo de pico-segundos (1012 segundos).

Circuitos Combinatrios

51

Figura 60: Lei de Moore: o nmero de transistores por rea dobra a cada dois anos 35

Duas operaes booleanas que podem ser derivadas das operaes bsicas so NAND e NOR, cuja importncia vem do fato de que sua construo com transistores mais simples, como veremos a seguir. Estas operaes so definidas por: NAND = (. ) NOR = ( + )

Ou seja, um NAND um AND seguido de uma negao, assim como um NOR um OR seguido de uma negao. A Figura 61 mostra os smbolos utilizados no desenho de circuitos lgicos para as portas NAND e NOR. Repare que o smbolo para NAND quase igual ao smbolo usado para AND, diferenciando-se somente por um pequeno crculo em sua sada; o mesmo vale para o smbolo usado para NOR.

35

Moores law - Wikipedia, the free encyclopedia, acessado 3 de maro de 2013, http://en.wikipedia.org/wiki/Moore_Law.

Circuitos Combinatrios

52

Figura 61: Smbolos para portas NAND e NOR

A Figura 62 mostra caractersticas que distinguem as operaes AND, OR, NAND e NOR.

AND(a,b) S igual a 1 quando a e b so iguais a 1 OR(a,b) S igual a 0 quando a e b so iguais a 0

NAND(a,b) S igual a 0 quando a e b so iguais a 1 NOR(a,b) S igual a 1 quando a e b so iguais a 0

Figura 62: Caractersticas de AND, NAND, OR e NOR

Transistores podem ser e so utilizados para amplificar sinais, mas, em circuitos digitais, funcionam essencialmente como interruptores, trabalhando ora como condutores perfeitos, ora como isolantes perfeitos.

Voltagem de Controle

Voltagem naEntrada

Voltagem na Sada

Figura 63: Smbolo de um transistor usado em diagramas de circuitos

Um transistor tem 3 pinos: um controle, uma entrada e uma sada. Em circuitos digitais o seu funcionamento se d somente nas seguintes situaes:

Circuitos Combinatrios quando a voltagem aplicada ao controle alta (para algumas tecnologias, 5 volts), o transistor um condutor perfeito, o que faz com que as voltagens na entrada e na sada sejam iguais; quando a voltagem aplicada ao controle baixa (0 volts, digamos), o transistor um isolante perfeito, e as voltagens na entrada e na sada podem diferir.

53

Vejamos inicialmente como uma porta NOT implementada com a utilizao de um transistor. Suponhamos que estamos representando o smbolo 0 por uma voltagem baixa e o smbolo 1 por uma voltagem alta. Como mostrado na Figura 64, uma fonte de voltagem alta ligada entrada do transistor, atravs de uma resistncia, enquanto a sada do transistor ligada um ponto de terra. A varivel que desejamos negar, , ligada ao controle do transistor. O resultado do circuito, , obtido no ponto entre a resistncia e a entrada do transistor.

Fonte V= 5 (voltagem alta)

a 1

a 0

Terra V= 0 (voltagem baixa)

Figura 64: Uma porta NOT invertendo a = 0. Como a = 0, o transistor funciona como isolante perfeito

Quando = 0, a voltagem aplicada ao controle do transistor baixa e ele funciona como isolante perfeito, e obtemos = 1.

Fonte V= 5 (voltagem alta)

a 0

a 1

Terra V= 0 (voltagem baixa)

Figura 65: Porta NOT invertendo a = 1. O transistor funciona como condutor perfeito

Quando = 1, o transistor funciona como condutor perfeito, e obtemos = 0, pois o contato com o ponto de terra estabelecido.

Circuitos Combinatrios

54

Fonte

0 (a + b) a 1

b 0 Terra

Figura 66: Uma porta NOR construda com dois transistores

Uma porta NOR construda com o arranjo de transistores mostrado na Figura 66; no difcil ver que o ponto ( + ) s ter o valor 1 (voltagem alta) quando os dois transistores do arranjo estiverem funcionando como isolantes, o que s ocorre quando = 0 e = 0.
Fonte

1 (a.b) a 1

b 0 Terra

Figura 67: Uma porta NAND implantada com transistores

Uma porta NAND construda de forma similar, mas com os transistores ligados em srie, como mostra a Figura 67. Aqui a sada (. ) s ser igual a zero quando tivermos = 1 e = 1, valores que fazem com que a sada esteja conectada ao ponto de terra.

Circuitos Combinatrios

55

Fonte

Fonte

a.b 0
a 1

b 0

Terra

NAND

NOT

Figura 68: Porta AND com 3 transistores

Para obter uma porta AND usando transistores basta inverter a sada de uma porta NAND, como mostrado na Figura 68. Uma porta OR pode tambm ser obtida conectando a sada de uma porta NOR com a entrada de uma porta NOT.

2.4 Introduo ao Logisim


O Logisim36 um simulador de circuitos lgicos, com objetivos didticos, que voc deve baixar pela Internet e instalar em seu computador. Este texto segue o tutorial que pode ser visto na ajuda do sistema. Ao iniciar o Logisim voc ver uma tela como a mostrada na Figura 69, talvez diferindo em alguns detalhes. Ali podemos ver uma barra de menu, cons de componentes de uso frequente, um cardpio de componentes e um painel para o desenho efetivo de circuitos.

36

Carl Burch, Logisim, acessado 20 de agosto de 2011, http://ozark.hend rix.edu/~burch/logisim/.

Circuitos Combinatrios

56

Componentes de uso frequente

rea de desenho de circuitos Cardpio de portas e outros circuitos

Figura 69: Tela inicial do Logisim

Para o nosso primeiro circuito, vamos implementar uma operao lgica importante, o Ou Exclusivo, escrito frequentemente como XOR (exclusive or). Se a e b so variveis booleanas (isto , variveis cujos nicos valores possveis so Verdadeiro e Falso, ou 0 e 1), a XOR b s tem o valor 1 (Verdadeiro) quando uma e somente uma das variveis a e b tem o valor 1. O Ou Exclusivo no uma operao primitiva da lgebra booleana, pois pode ser obtido atravs da expresso a XOR b = ab + ab. Vamos comear colocando duas portas AND, clicando sobre o smbolo correspondente na barra de componentes de uso frequente, e posicionando as portas na rea de desenho, como mostrado na Figura 70. Repare na tabela de atributos, que exibe e permite a edio de dados relativos ao elemento selecionado no caso, a porta AND inferior.

Circuitos Combinatrios

57

Porta AND

Componente selecionado

Atributos do componente selecionado

Figura 70: Duas portas AND

Depois, usando ainda a barra de ferramentas, vamos colocar uma porta OR e duas NOT, posicionando-as conforme a Figura 71.

NOT

OR

Figura 71: Acrescentando portas NOT e OR

O prximo passo a colocao de entradas e sadas, que so colocadas usando os cones em destaque na Figura 72.

Circuitos Combinatrios

58

Entrada

Sada

Figura 72: Acrescentando entradas e sadas

Para colocar fios ligando entradas, portas e sadas, utilize a ferramenta de seleo em destaque na Figura 73. Fios sempre seguem caminhos que so composies de segmentos horizontais ou verticais, chamados caminhos Manhattan.

Seleo

Figura 73: Acrescentando o cabeamento

Circuitos Combinatrios

59

Neste ponto voc j pode notar convenes de cores usadas pelo Logisim: preto usado para cabos com valor 0, verde para 1, e azul para cabos ainda sem valor determinado. Termine agora o cabeamento para obter o circuito da Figura 74 que implementa o Ou Exclusivo.

Contato

Cruzamento sem contato

Figura 74: Circuito OU Exclusivo

Seu diagrama ficar mais fcil de ser compreendido se voc acrescentar textos, usando a ferramenta A em destaque na Figura 75. Voc pode alterar as caractersticas da fonte (tamanho, negrito ou itlico, etc.) editando os atributos do texto selecionado.

Texto

Rtulo

Figura 75: Acrescentando textos a um circuito

Circuitos Combinatrios

60

Textos podem ser colocados em qualquer posio na rea de desenho, mas muitas vezes melhor coloc-los como "rtulos" de elementos de circuito, como entradas, portas lgicas e sadas. O rtulo acompanha o elemento de circuito quando este movido para outra posio. Para isto, selecione o elemento, e preencha o campo Rtulo na tabela de atributos, como mostrado na Figura 75.

Ferramenta de simulao

Figura 76: Ferramenta de simulao

Para testar o seu circuito, use a ferramenta de simulao a mozinha em destaque na Figura 76. Utilize-a clicando sobre as entradas do circuito para alterar o seu valor. Explore todas as combinaes possveis de valores para a e b, verificando a sada para completar a tabela da Figura 77. A 0 0 1 1 B 0 1 0 1 a XOR b

Figura 77: Complete com os valores produzidos pelo seu circuito XOR

Circuitos podem ser salvos em arquivos para uso posterior. Para salvar o seu circuito, use a opo Arquivo/Salvar do menu do Logisim, escolha um nome para o arquivo e um diretrio, e salve-o. Para voltar a trabalhar com o arquivo, use Arquivo/Abrir. Para introduzir elementos de circuito com outras orientaes, clique sobre a porta desejada, e depois altere o campo Posio na tabela de atributos, conforme mostrado na Figura 78.

Circuitos Combinatrios

61

Figura 78: Mudando a orientao de um componente de circuito

Se voc seguiu todos os passos deste roteiro, ter assimilado os elementos bsicos para o uso do Logisim. Voc pode descobrir muito mais lendo a ajuda ou explorando diretamente a ferramenta.

2.5 Soma de duas parcelas de 1 bit

Figura 79: Circuito correspondente expresso a'(ca)'(b'+c)

Ns vimos como circuitos lgicos implementam expresses lgicas, com um mapeamento direto. Por exemplo, a Figura 79 mostra um circuito que corresponde expresso () ( + ). No difcil acreditar que conseguimos obter circuitos para qualquer expresso lgica. Mas podemos fazer circuitos lgicos que fazem contas? Ora, como o nome indica, computadores

Circuitos Combinatrios

62

computam, isto , fazem contas, e sabemos portanto que a resposta afirmativa. Mas como? o que veremos nesta seo. Vamos comear por um problema bem simples: encontrar um circuito lgico que faa a soma de dois inteiros representados como binrios sem sinal de 1 bit cada um. Na base dez, o resultado pode ser 0, 1 ou 2. Portanto o resultado, tambm codificado como binrio sem sinal, pode ser 00, 01 ou 10. Ou seja, sero necessrios 2 bits para representar o resultado da soma de duas variveis de 1 bit. importante entender que somar significa obter a representao como um binrio sem sinal da soma das entradas , entendidas tambm como binrios sem sinal. Na verdade, calcular ou computar uma funo qualquer significa transformar a representao de seus argumentos na representao do valor da funo, coisa que j fazemos ao seguir as regras da aritmtica que aprendemos no ensino primrio. A Figura 80 mostra as entradas e sadas do circuito que pretendemos construir.

Entradas 1 bit cada

Circuito Somador 1 bit


Sadas

s1 s0

Notao comum para conjuntos de bits: 0 o ndice do bit menos significativo

Figura 80: Entradas e sadas de um somador de 1 bit

Para especificar exatamente qual a transformao de informao que esperamos deste circuito, vamos utilizar uma tabela da verdade. Uma tabela da verdade apresenta o valor de uma ou mais funes lgicas as sadas do circuito correspondendo a cada combinao possvel de valores das variveis de entrada. A Figura 81 mostra a tabela da verdade para a soma de duas variveis de 1 bit.
Sadas: 2 funes lgicas das mesmas variveis

Entradas

Todos os valores possveis para as entradas

Resultados da soma em binrio sem sinal

Figura 81: Tabela da Verdade para soma de duas variveis de 1 bit

Circuitos Combinatrios Nessa tabela ns temos:

63

duas variveis de entrada, e ; duas funes de sada, 1 e 0; cada funo corresponde a um dgito binrio do resultado; a cada linha da tabela corresponde uma combinao das variveis de entrada e o valor correspondente das funes de sada. Como so duas variveis, temos 22 = 4 linhas na tabela.

Tabelas da verdade constituem um mecanismo geral para a especificao de funes lgicas. Elas especificam as sadas para cada combinao possvel das variveis de entrada. Ns j vimos tabelas da verdade quando introduzimos as funes NOT, AND e OR, na Seo 2.2. Dada uma expresso lgica, ns podemos construir sua tabela da verdade efetuando as operaes da expresso. A Figura 82 mostra a tabela da verdade para a expresso ( + ), contendo valores intermedirios usados no clculo do valor da expresso. 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 1 1 1 1 0 0 0 0 + 0 1 1 1 0 1 1 1 ( + ) 0 1 1 1 0 0 0 0

Figura 82: Tabela da verdade para a expresso ( + )

Mas nosso problema no bem esse. Ns temos uma tabela da verdade e, para obter um circuito lgico para uma das funes de sada a partir de uma tabela da verdade preciso: conseguir uma expresso lgica equivalente tabela da verdade, e construir o circuito equivalente expresso lgica.

Uma expresso lgica e uma funo definida por uma tabela da verdade so equivalentes quando para qualquer combinao de valores das variveis de entrada, os valores da funo e os valores da expresso so iguais. Por exemplo, a funo f(x, y) definida pela tabela mostrada na Figura 83 equivalente expresso (, ) = + .

f(x,y)

0 0 1 1

0 1 0 1

1 0 0 1

Figura 83: Tabela da verdade para a funo f(x,y)

Um mtodo genrico para se obter uma expresso lgica para uma funo definida por uma tabela da verdade consiste em fazer um OR de termos que s tm o valor 1 para cada combinao das variveis de entrada para a qual o valor da funo igual a 1.

Circuitos Combinatrios

64

x 0
0

y 0
1

f(x,y) 1
0

xy + xy

1
1

0
1

0
1

Figura 84: Cobertura dos 1s de uma funo booleana

Na Figura 84, (, ) = 1 somente na primeira linha, quando = 0 e = 0, e na ltima linha, quando = 1 e = 1. Ns temos: = 1 se e somente se = 0 e = 0; para qualquer outra combinao de valores de e , = 0 = 1 se e somente se = 1 e = 1.; para qualquer outra combinao de valores de e , = 0.

Portanto, o OR destes dois termos, (, ) = + , cobre exatamente os 1s da tabela, e uma expresso lgica equivalente funo desejada. A expresso assim obtida chamada de soma cannica associada funo.
s0 = ab + ab

s1 = ab

Figura 85: Expresses lgicas para um somador de duas variveis de 1 bit

Retornando ao problema do somador de 1 bit, temos duas funes para as quais queremos encontrar expresses lgicas equivalentes. Na Figura 85 vemos que, para a funo 1, temos apenas o 1 da ltima linha a cobrir, o que feito pelo termo , e para a funo 0, temos um 1 na segunda linha, coberto pelo termo , e outro 1 na terceira linha, coberto pelo termo . Ou seja, as expresses lgicas que desejamos so 0 = + e 1 = . A Figura 86 mostra um circuito que implementa essas expresses lgicas. Este circuito conhecido como circuito meia-soma, por contraste com o circuito soma-completa que veremos a seguir.

Circuitos Combinatrios

65

ab ab

ab

Figura 86: Circuito lgico para soma binria de 1 bit, ou circuito meia-soma

Temos aqui um resultado importantssimo: construimos um circuito lgico com duas entradas de 1 bit representando binrios sem sinal, e que produz em sua sada dois bits representando a soma das entradas, tambm codificado como um binrio sem sinal. Como prometemos, conseguimos fazer contas com as funes lgicas NOT, AND e OR.

2.6 Soma de dois inteiros com vrios bits


Tudo bem, conseguimos fazer um circuito que realiza a soma de duas variveis de 1 bit. Uma faanha, mas em termos prticos, muito pouco. Para fazer qualquer coisa mais sria, precisamos ser capazes de somar variveis de, digamos, 32 bits, como so representados inteiros em boa parte dos computadores atuais. Em princpio ns poderamos construir uma tabela da verdade com as entradas e sadas, e depois inferir expresses lgicas para as sadas usando o mtodo de cobertura dos 1s. Essa tabela teria 64 bits de entrada, correspondendo s duas variveis a serem somadas, e 33 bits de sada, pois a soma de duas variveis de 32 bits pode ter 33 bits. O problema que essa tabela teria 264 ou aproximadamente 1064/3,3 1019 linhas. Para entender, considere a equao 2 = 10 = (22 (10) ) = 22 (10) , ou =
2 (10)

3,3).

Vamos nos situar. Um ano tem somente 3,1536 1016 nano-segundos, e um nano-segundo a ordem de grandeza do tempo de reao de portas lgicas na tecnologia atual. Se considerarmos que a anlise de cada linha da tabela tomaria 1 nano-segundo, o que de um enorme otimismo, a obteno da expresso para a soma tomaria no mnimo 3.000 anos. Ou seja, mesmo se teoricamente conseguiramos construir o somador de 32 bits pelo mtodo de cobertura dos 1s, na prtica isso absolutamente invivel. Temos portanto que adotar outro enfoque. Primeiramente vamos examinar como ns, humanos, fazemos uma soma em binrio. Depois, vamos construir um somador de forma modular, explorando regularidades no processo de soma. Nmeros binrios adotam a notao posicional, a mesma adotada no sistema decimal que usamos no dia a dia, cujo imenso sucesso se deve exatamente facilidade com que operaes aritmticas so feitas. Uma soma de nmeros binrios similar soma decimal que aprendemos na escola primria um algoritmo venervel, difundido no Ocidente por ningum

Circuitos Combinatrios

66

menos que Muammad ibn Ms al-Khwrizm, matemtico rabe37 que viveu entre 780 e 850 em Bagd, e cujo nome traduzido para o latim deu origem palavra algoritmo. Para entender o sucesso do ento novo mtodo, que concorria com nmeros romanos, responda rbido, quanto vale LIII + XXVIII? E, pior, quanto vale LIII XXVIII? Para fazer uma soma na base 10 ns somamos algarismo por algarismo, da direita (menos significativos) para a esquerda (mais significativos). Quando a soma de dois algarismos excede 9, colocamos como resultado daquela coluna somente o seu dgito mais significativo, e acrescentamos 1 (o vai-um) na soma da coluna seguinte (Figura 87).

Vai-um a b a+b

1 2 4 7

1 7 7 6 7 9 1 5 6 7

Figura 87: Soma em decimal

Para somar dois nmeros binrios o procedimento anlogo. Somamos bit a bit, da direita para a esquerda e, quando a soma de uma coluna excede 1, colocamos como resultado da coluna somente o bit mais significativo de sua soma, e temos um vai-um para a coluna seguinte. A Figura 88 mostra o processo do clculo de 1011101+1001110.
Vai-Um 1 0 1 1 1 0 1 0 0 1 1 1 0 0 1 1 1 1 0 1 1 0 0 0 1 1 1 0 1

Parcelas

Soma

Figura 88: Exemplo de soma de binrios

Ns vamos usar essa aritmtica para construir um circuito somador de vrios bits. A idia construir um mdulo que faa a operao de uma das colunas da soma. O somador ter tantos deste mdulo quantas forem as colunas, ou seja, tantos mdulos quantos forem os bits das parcelas.

37

Muammad ibn Ms al-Khwrizm - Wikipedia, the free encyclopedia.

Circuitos Combinatrios

67

vai-um soma

SC

vem-um

a
b

Figura 89: Entradas e sadas de um circuito de soma completa

Este mdulo, esquematizado na Figura 89, ter trs entradas: os dois bits de uma coluna das parcelas, e uma entrada que vamos chamar de vem-um, que vamos ligar sada vai-um da coluna direita,

As sadas do mdulo so duas: um bit de resultado um bit de vai-um, que ser ligado entrada vem-um da coluna esquerda.

Um circuito que implemente esse mdulo conhecido como circuito soma-completa.

Circuito Soma-Completa

Igual a 1 quando a soma tiver 5 bits

vem-um do bit menos significativo sempre zero

Figura 90: Arranjo em cascata de mdulos para um somador de 4 bits

A Figura 90 mostra um arranjo em cascata de circuitos de soma completa, capaz de somar duas variveis de 4 bits. O mdulo SC (Soma Completa) mais direita faz a soma dos bits menos significativos de cada parcela, 0 e 0 . Sua entrada vem-um recebe o valor constante 0. Ele produz um bit de resultado, 0, e o vai-um da coluna, que conectado entrada vemum do segundo SC da direita para a esquerda. Este segundo SC faz a soma de 1 , 1 e de sua entrada vem-um que, como dissemos, o vai-um do primeiro SC. E esse arranjo se repete, aqui para os 4 bits das parcelas, mas poderia se repetir por 32, ou por 64, ou por 128 vezes. Em um somador de bits, o circuito de soma completa do bit mais significativo produz um vaium que indica que a soma das parcelas s pode ser representada com + 1 bits. Essa situao designada por estouro, ou mais comumente, pelo termo em ingls overflow.

Circuitos Combinatrios

68

soma = abv + abv + abv + abv


a 0 b 0 vem-um 0 soma 0 vai-um 0

0 0
0 1

0 1
1 0

1 0
1 0

1 1
0 1

0 0
1 0

1
1 1

0
1 1

1
0 1

0
0 1

1
1 1

vai-um = abv + abv + abv + abv

Figura 91: Tabela da verdade para um circuito de soma completa

A Figura 91 mostra a tabela da verdade para um circuito de soma completa, e as expresses encontradas pelo mtodo de cobertura dos 1s para as sadas soma e vai-um. A varivel designa aqui a entrada vem-um.

Figura 92: Circuito Soma Completa, construdo diretamente a partir das expresses obtidas da tabela da verdade

A Figura 92 mostra um circuito de soma completa construdo com a utilizao destas expresses lgicas.

Circuitos Combinatrios

69

Figura 93 Somador de 4 bits, usando 4 circuitos de Soma Completa

Podemos agora obter somadores de bits, compondo circuitos de Soma Completa seguindo o arranjo proposto na Figura 90. A Figura 93 mostra um somador de 4 bits obtido com este desenho.

2.7 Modularizao e Sntese Automtica de Circuitos Combinatrios no Logisim


A extrao de uma expresso lgica (e do circuito correspondente) a partir de uma tabela da verdade um processo que pode ser automatizado, e o Logisim oferece esta possibilidade. Vamos aqui reconstruir o circuito de soma completa a partir de sua tabela da verdade, usando o Logisim, e vamos aproveitar para aprender como construir e utilizar mdulos neste sistema.

Figura 94: Abrindo a janela de anlise combinacional do Logisim

Abra o Logisim, e siga o menu Janela/Anlise Combinacional, como mostrado na Figura 94. Na janela Anlise Combinacional, na aba Entradas, insira os nomes a, b e v, que correspondem s entradas de um circuito de soma completa, como mostra a Figura 95.

Circuitos Combinatrios

70

Figura 95: Definindo no Logisim as entradas do circuito

Na aba Sadas, insira os nomes VaiUm e Soma, conforme mostra a Figura 96.

Figura 96: Definindo no Logisim as sadas de um circuito

Depois, clique sobre a aba Tabela, e entre com a tabela da verdade para o circuito de soma completa, com os valores mostrados na Figura 91.

Circuitos Combinatrios

71

Figura 97: Entrando com a tabela da verdade para a soma completa no Logisim

A Figura 97 mostra a tabela j com todos os valores inseridos. Isso feito clicando uma ou mais vezes sobre cada ponto nas colunas de sada da tabela; a cada clique, o valor trocado, indo de x para 0, de 0 para 1 ou de 1 para x.

Figura 98: Escolha do nome do novo circuito no Logisim

Quando a tabela estiver pronta, clique sobre o boto Construir Circuito, e d ao novo circuito o nome de Soma Completa, como mostrado na Figura 98.

Circuitos Combinatrios

72

Figura 99: Circuito de soma completa gerado automaticamente pelo Logisim a partir da tabela da verdade

Aperte o boto OK e... como mostra a Figura 99, nosso circuito de soma completa est pronto! Mas est um pouco diferente do circuito que j construmos, mostrado na Figura 92. No circuito sintetizado automaticamente pelo Logisim a sada vai-um dada pela expresso = + + onde designa a sada Vai-um. Isto no um erro, pois esta expresso equivalente expresso = + + + encontrada pelo mtodo de cobertura de 1s, o que voc pode verificar construindo uma tabela da verdade para as duas expresses. Pelo contrrio, a simplificao da expresso leva a um circuito mais simples e funcionalmente equivalente. Percebemos que o Logisim no somente realiza automaticamente o nosso mtodo de cobertura dos 1s, como tambm capaz de simplificar a expresso resultante. Vamos agora refazer o somador de 4 bits, desta vez usando mdulos. importante voc reparar que o Logisim criou o circuito Soma Completa como um sub-circuito, o que indicado no painel de componentes veja a seta na Figura 99. Para isto d um duplo clique sobre o subcircuito main. Voc ver o circuito main, vazio. Agora, d um clique sobre o sub-circuito Soma Completa no painel de componentes, dirija o mouse para o painel de desenho, e d outro clique na posio onde voc deseja colocar o primeiro sub-circuito de Soma Completa. Este sub-circuito aparece agora como um bloquinho sem detalhes internos, com pequenos pontos marcando seus pinos de entrada e sada. Passe com o mouse sobre essas entradas e sadas; o Logisim indica o nome de cada uma delas.

Circuitos Combinatrios

73

Figura 100: Colocando um sub-circuito de Soma Completa como um bloco no circuito principal. Esta tela foi capturada com o mouse sobre a entrada b do sub-circuito

Para obter exatamente o que est mostrado na Figura 100, ainda ser necessrio usar o painel de atributos para: mudar a posio do sub-circuito para Oeste, fazendo com que suas entradas fiquem direita do bloco, e as sadas esquerda, o que mais conveniente para o desenho do somador de 4 bits; colocar SC como rtulo compartilhado dos sub-circuitos de Soma Completa.

Circuitos Combinatrios

74

Figura 101: Iniciando o circuito somador de 4 bits, com os componentes de soma completa, entradas e sadas, e a constante 0 na entrada v do bit menos significativo

Como voc pode ver, subimos de nvel. No projeto do circuito somador de 4 bits, detalhes do sub-circuito Soma Completa, importantes para o seu projeto interno, podem ser esquecidos o que interessa agora somente sua funcionalidade.

Figura 102: Somador de 4 bits completo, utilizando sub-circuitos de soma completa

A Figura 102 mostra o circuito completo do somador de 4 bits. Compreender este circuito certamente muito mais fcil do que entender o somador da Figura 93.

Circuitos Combinatrios

75

2.8 Sntese de um display hexadecimal


Como um exemplo mais detalhado de sntese automtica de circuitos combinatrios a partir de sua tabela da verdade, vamos o usar o Logisim para construir um display hexadecimal, isto , um circuito que acende os filamentos correspondentes ao smbolo hexadecimal codificado em seus 4 bits de entrada em uma lmpada de 7 segmentos. Este um dispositivo simples e eficaz para a visualizao de algarismos decimais e de algumas letras, que voc certamente j viu em relgios, elevadores ou sintonizadores de TV a cabo.

Figura 103: Uma lmpada de 7 segmentos com todos os filamentos acesos

O Logisim oferece este componente, na biblioteca Entrada/Sada. Cada um dos pinos acente um dos filamentos, com exceo de um pino que acende um ponto decimal, que no vamos usar aqui.

Center Lower Left

Upper Right

Lower Right

Figura 104: Nomes dos pinos em uma lmpada de 7 segmentos

A Figura 104 mostra os rtulos dos pinos de entrada de uma lmpada de 7 segmentos, e na Figura 105 ns vemos o arranjo de entradas e sadas do circuito que iremos sintetizar (o display hexadecimal j existe tambm pronto no Logisim, mas vamos reconstru-lo).

Circuitos Combinatrios

76

4 bits de entrada

Circuito que queremos

Figura 105: Arranjo de entradas e sadas de circuito de controle de um display hexadecimal

Para isso, abrimos a janela Anlise Combinacional do Logisim, e construmos uma tabela da verdade com 4 entradas, a3, a2, a1 e a0, e com 7 sadas, UL, U, C, UR, LL, P, L e LR. Para cada linha colocamos 1 nas sadas correspondentes aos filamentos que, acesos, compem o dgito hexadecimal formado pelos bits de entrada. A tabela final est mostrada na Figura 106.

Figura 106: A tabela da verdade completa para o display hexadecimal, com destaque para a determinao das sadas para formar um F

Feito isso, basta apertar Construir circuito para obter o circuito da Figura 107. O circuito parece complicado? Pode ser, mas isso no um problema. O circuito foi construdo automaticamente, a partir de uma tabela da verdade, usando algoritmos do Logisim que so melhorias do mtodo que vimos para obteno de somas cannicas. Isso nos garante a sua correo. E ele pode ser usado como um mdulo, esquecendo completamente seus detalhes, como fizemos na Figura 105.

Circuitos Combinatrios

77

Figura 107: Circuito gerado automaticamente pelo Logisim para o controlador de display hexadecimal

2.9 Comparao de binrios sem sinal


a Comparador b

a<b

a=b

a>b

Figura 108: Entradas e sadas de um circuito comparador

Vimos na seo 2.5 que circuitos lgicos podem realizar operaes aritmticas. Vamos agora atacar o problema de construir circuitos lgicos que permitam comparar duas variveis e de, digamos, 32 bits cada uma, codificadas como binrios sem sinal. A sada do circuito deve indicar se = , < ou > , como mostrado na Figura 108. Aqui tambm temos problemas com o uso do mtodo de cobertura de 1s na tabela da verdade, que teria as mesmas 264 linhas da tabela do somador de 32 bits. Vamos aplicar o mesmo enfoque que usamos na soma: verificar como fazemos a comparao, e procurar resolver o problema por etapas que seriam feitas por mdulos menores.

Circuitos Combinatrios

78

a b aMaior abIguais bMaior 0 1 0

1 1 0 1 0

1 1 0 1 0

1 1 0 1 0

1 0 1 0 0

1 1 1 0 0

0 1 1 0 0

0 1 1 0 0

0 0 1 0 0

a b aMaior abIguais bMaior 0 1 0

0 1 0 0 1

1 1 0 0 1

1 1 0 0 1

1 0 0 0 1

1 1 0 0 1

0 1 0 0 1

0 1 0 0 1

0 0 0 0 1

a b aMaior abIguais bMaior 0 1 0

1 1 0 1 0

1 1 0 1 0

1 1 0 1 0

0 0 0 1 0

1 1 0 1 0

0 0 0 1 0

1 1 0 1 0

0 0 0 1 0

Figura 109: Casos de comparao entre as entradas a e b.

fcil ver que, ao comparar dois binrios de mesmo tamanho, sem sinal, devemos comparar bit a bit, comeando com o bit mais significativo. Na primeira diferena, j podemos concluir que a parcela com o bit igual a 1 definitivamente a maior, e os bits restantes, que so menos significativos, no interessam para o resultado final. A Figura 109 mostra trs casos de comparao de entradas e , cada uma com 8 bits. No primeiro caso as entradas diferem no quarto bit mais significativo, e > . No segundo caso as entradas j diferem no primeiro bit mais significativo, e > . No terceiro caso as entradas so iguais. Para construir um circuito que faa a comparao de binrios sem sinal ns precisamos de um comparador de 1 bit que leve em considerao a possibilidade do resultado j ter sido estabelecido por algum bit mais significativo.
Bit corrente

a b aMaior
bMaior Mdulo Comparador de 1 bit Amaior

Bmaior ABiguais

abIguais

Vm do comparador esquerda

Vo para o comparador direita

Figura 110: Entradas e sadas para um mdulo comparador de 1 bit

Vemos na Figura 110 um esquema de entradas e sadas para o mdulo comparador de 1 bit. As entradas a e b vm do bit em questo das variveis que estamos comparando. Da comparao

Circuitos Combinatrios

79

j feita com bits mais significativos que o bit em questo vm as entradas aMaior, bMaior e abIguais. A Figura 111 mostra o arranjo de mdulos que compem um comparador de 4 bits.

Entrada b

Entrada a

Para o bit mais significativo, aMaior = bMaior = 0, e abIguais = 1

Figura 111: Arranjo de mdulos para um comparador de 4 bits

Temos um mdulo comparador para cada bit das variveis de entrada. Cada mdulo comparador tem cinco entradas: Duas so os bits das entradas da coluna correspondente ao mdulo; As trs outras so designadas por aMaior, bMaior e abIguais, e, exceto para o mdulo mais esquerda, so produzidas pelo mdulo comparador esquerda do mdulo em questo. Elas tm o resultado da comparao j realizada com os bits mais significativos e portanto, uma e somente uma dessas entradas poder ter o valor 1. Para o mdulo mais esquerda, que corresponde ao bit mais significativo, ns impomos o valor 1 para a entrada abIguais, e 0 para aMaior e bMaior.

A Figura 112 mostra as primeiras linhas de uma tabela da verdade para o mdulo comparador de 1 bit; a tabela completa tem 25 = 32 linhas. A coluna aMaior uma entrada desse mdulo, enquanto a coluna Amaior uma sada. A mesma conveno usada para bMaior, Bmaior, abIguais e ABiguais. Combinaes onde mais de uma dentre as variveis aMaior, bMaior e abIguais tm o valor 1 ou em que todas as trs so iguais a 0 nunca devem ocorrer, e o smbolo usado na tabela para indicar que os valores das sadas no tm interesse nesses casos. O Logisim tira proveito disso para obter circuitos mais simples.

Circuitos Combinatrios

80

Estas sadas vo para a coluna direita

Estas entradas vm da coluna esquerda

x usado quando a combinao de entradas nunca ocorre o Logisim simplifica o circuito


Figura 112: Tabela da verdade para um comparador de 1 bit

A Figura 113 mostra o circuito comparador de 1 bit obtido dessa tabela da verdade.

Figura 113: Circuito comparador de 1 bit

Circuitos Combinatrios

81

2.10 Multiplexadores, Demultiplexadores e Decodificadores


Conduzir bits de um lugar para outro essencial para o funcionamento de um computador, para conduzir dados a circuitos capazes de, por exemplo, efetuar operaes aritmticas. Ns veremos agora multiplexadores e demultiplexadores, que so circuitos que conectam entradas e sadas de acordo com um endereo e o endereo tambm uma entrada.

Determina qual das entradas fica conectada sada

Determina qual das sadas fica conectada entrada

Figura 114: Multiplexadores (MUX) e Demultiplexadores (DMX)

Como mostra a Figura 114, Um multiplexador conecta uma nica entre vrias entradas de dados a um destino; a entrada escolhida designada por um endereo; Um demultiplexador conecta uma entrada de dados a um dentre vrios destinos; o destino escolhido designado por um endereo.
a, de address, determina qual entrada ser encaminhada para a sada Out

out = In0 quando a=0

out = In1 quando a=1

Figura 115: Tabela da verdade para um multiplexador de 1 bit

A Figura 115 mostra uma tabela da verdade para um multiplexador de 1 bit de endereo. Esse circuito tem trs entradas: In0 e In1, que so as variveis fonte de informao, e o endereo a, que decide qual dentre In0 e In1 ser conectada sada out.

Circuitos Combinatrios

82

out0 = In quando a=0 a (address) indica para qual sada a entrada In ser copiada
out1 = In quando a=1

Figura 116: Tabela da verdade para um demultiplexador de 1 bit

Na Figura 116 ns vemos a tabela da verdade para um demultiplexador de 1 bit. Esse circuito tem as entradas a e In. A entrada a um endereo de 1 bit e que designa qual das sadas, out0 ou out1, ser conectada entrada fonte de informao In.

Figura 117: Circuito multiplexador de 1 bit

Multiplexadores de 1 bit tambm podem ser usados como mdulos para a construo de multiplexadores de mais bits, com o arranjo mostrado na Figura 118.

O binrio a1a0 designa qual entrada fica ligada sada

Figura 118: Um multiplexador de 2 bits obtido usando multiplexadores de 1 bit

A Figura 119 mostra o circuito demultiplexador de 1 bit obtido a partir da tabela da verdade da Figura 116.

Circuitos Combinatrios

83

Figura 119: Circuito demultiplexador de 1 bit

Demultiplexadores com uma largura de endereo (nmero de bits de endereo) maior tambm podem ser obtidos com arranjos hierrquicos similares, como mostra a Figura 120.

DMX 1 bit DMX 1 bit DMX 1 bit

Figura 120: Circuito demultiplexador de 2 bits, obtido a partir de demultiplexadores de 1 bit

Um decodificador um circuito com entradas de 1 bit, e 2 sadas de 1 bit. Destas, uma e apenas uma ter o valor 1 aquela cujo endereo a decodificao do valor codificado como binrio sem sinal nas entradas. Um decodificador pode ser obtido usando um demultiplexador, como mostra a Figura 121.

Entrada codificada em binrio

Constante 1

Sada decodificada

Figura 121: Decodificador de 3 bits

Circuitos Sequenciais

84

3 Circuitos Sequenciais
Ns vimos que circuitos combinatrios podem, com arranjos adequados, fazer operaes aritmticas ou comparaes com operandos de 32 ou 64 bits. Mas seria possvel construir um circuito combinatrio para realizar a soma de, digamos, um milho de parcelas de 32 bits cada? Teoricamente sim, mas na prtica isso no feito no somente por dificuldades tcnicas, mas tambm porque muito mais simples realizar esta soma parcela por parcela, acumulando resultados parciais em alguma memria. Para isso so utilizados circuitos seqenciais, que diferem dos circuitos combinatrios por serem capazes de armazenar dados. Em um dado instante as sadas de um circuito sequencial no dependem apenas dos valores correntes de suas entradas, como nos circuitos combinatrios, mas so tambm funes de valores armazenados em suas memrias.

3.1 Flip-flops e Registradores


Poderia ser click; funciona como um obturador de mquina fotogrfica Bit Armazenado

Complemento do Bit Armazenado

A entrada D fotografada no instante em que o clock passa de 0 para 1

Pino Auxiliar: Impe 0 Pino Auxiliar: Impe 1


Pino Auxiliar: Habilita o FF

Figura 122: Flip-flop tipo D

O circuito seqencial mais bsico conhecido pelo nome em ingls de flip-flop, e, como sempre comeamos pelos casos mais simples, um flip-flop capaz de armazenar um nico bit. Existem vrios tipos de flip-flop, mas aqui ns s veremos flip-flops do tipo D. A Figura 122 mostra um flip-flop tipo D disponvel no Logisim, e que possui 5 pinos: Pino D: onde fica a informao o Dado de entrada que pode vir a ser armazenada no flip-flop; Pino Clock: um pino que funciona como um obturador de uma mquina fotogrfica. No exato instante em que o sinal aplicado ao Clock passa de 0 para 1, o flip-flop passa a armazenar o valor corrente do pino Input. O nome clock vem do fato deste sinal frequentemente se originar de uma fonte de tempo, como veremos mais tarde. Click seria um nome mais adequado para a analogia com a mquina fotogrfica. Pino Q: uma sada que tem o valor armazenado no flip-flop; Pino Q: uma sada que tem o complemento do valor armazenado no flip-flop; Pinos Set e Reset: so entradas auxiliares que facilitam a imposio de um valor para o flip-flop. Essas entradas so normalmente usadas para inicializao ou re-inicializao do flip-flop.

Circuitos Sequenciais Pino Enable: uma entrada auxiliar que serve para habilitar ou inibir o comportamento do 7 flip-flop.
6

85

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

Clock
4 3

D
2 1

Q
0 -1

Tempo
Figura 123: Carta de tempo para um flip-flop tipo D. As setas destacam os instantes de subida do clock, quando a entrada D copiada pelo flip-flop.

A Figura 123 mostra um grfico uma carta de tempo que ilustra um exemplo de evoluo temporal de um flip-flop tipo D, onde: no instante 1 as entradas D e Clock valem 0, assim como a sada Q; nos instantes 2, 3 e 4 respectivamente a entrada D muda de 0 para 1, de 1 para 0 e de 0 para 1 novamente, sem que isso afete a sada Q, pois a entrada Clock permanece em 0 durante esse intervalo; no instante 5 a entrada Clock sobe, mudando de 0 para 1. a este sinal que o flip-flop reage, copiando (fotografando) a entrada D. Com isso o bit armazenado muda tambm de 0 para 1; no instante 6 a entrada Clock desce, mas isso no afeta o estado do flip-flop; nos instantes 7, 8 e 9 a entrada D oscila novamente, sem afetar o estado do flip-flop; no instante 10 o sinal do Clock sobe, e a sada Q passa para 0, copiando o valor de D nesse instante;

E por a vai.
Clock nico para os 4 FFs

Sadas

Entradas

Figura 124: Um registrador de 4 bits formado por flip-flops tipo D

Circuitos Sequenciais

86

Flip-flops podem ser agrupados formando registradores, que so conjuntos de flip-flops com alguma misso em comum. A Figura 124 mostra um registrador de 4 bits, cuja funo similar de um nico flip-flop, mas com capacidade para armazenamento de 4 bits. Ele composto por flip-flops do tipo D, e podemos reparar na figura que: um mesmo sinal de clock comanda os 4 flip-flops; na subida deste sinal, isto , quando o clock passa de 0 para 1, as quatro entradas D so copiadas para os flip-flops; uma entrada Reset coloca 0 em todos os flip-flops, ao receber um sinal 1.

O Logisim oferece uma srie de circuitos j prontos, que encontram-se armazenados em bibliotecas, e que podem ser utilizados como peas para a montagem de circuitos maiores, da mesma forma como j usamos portas lgicas. Flip-flops tipo D, outros tipos de flip-flop, registradores e vrios outros componentes se encontram na biblioteca Memria.

Registradores

Valor armazenado no registrador, em hexadecimal

Largura de dados

Figura 125: Um registrador da biblioteca Memria do Logisim, com largura de 8 bits

Registradores do Logisim so sempre apresentados como um nico bloco que se assemelha a um flip-flop, mas que capaz de armazenar um nmero de bits escolha do usurio. Um cabo conectado entrada D de um registrador de 4 bits deve tambm ter uma largura de 4 bits.

Circuitos Sequenciais

87

Figura 126: Dois circuitos equivalentes. No circuito de cima, fios e registradores tm 1 bit de largura; no de baixo, 4 bits

Na Figura 126 ns vemos dois circuitos equivalentes, cada um com dois registradores de 4 bits conectados. O circuito de cima utiliza somente elementos de largura de 1 bit, com os quais j estamos familiarizados. O de baixo utiliza entradas, sadas, registradores e cabos de 4 bits de largura. Seu desenho por isso mesmo muito mais simples e, portanto, de mais fcil compreenso. A largura de bits de componentes como registradores, entradas e sadas controlada pelo usurio, usando o campo Bits de Dados no painel de atributos, como na Figura 125. O Logisim facilita a nossa vida dando a cabos a largura de bits dos componentes aos quais o cabo se conecta, e alertando o usurio nos casos de incompatibilidade.
Traduo errada! Deveria ser ramos de sada
3 bits 2 bits

8 bits 3 bits

Figura 127: Uma bifurcao de um cabo de 8 bits em um de 2 bits e outros dois de 2 bits de largura. O retngulo esquerda uma ampliao do painel de atributos da bifurcao

O Logisim oferece ainda bifurcaes (splitters) que permitem dirigir os bits de um cabo com largura maior para outros de largura menor, como mostrado na Figura 127.

Circuitos Sequenciais

88

3.2 Barramentos e Controle de Fluxo de Dados

Toda sada ligada ao barramento passa por um Controlled Buffer

A todo instante, no mximo um controlled buffer pode ter o controle do barramento

O dado no barramento igual sada com o controlled buffer ligado

Figura 128: Um barramento conectando uma entrada de 8 bits e trs registradores

Nos circuitos que vimos at agora um cabo s pode ser usado para conectar uma sada de um componente a uma ou mais entradas de outros componentes. Essa restrio vem por um lado da falta de sentido lgico nesse tipo de conexo: se uma das sadas tem 0 e outra 1, qual valor fica no barramento? Por outro lado, vem tambm dos circuitos reais: se uma de duas sadas conectadas a um cabo tem o valor 0 e outra tem o valor 1, temos uma voltagem alta ligada diretamente a uma voltagem baixa, ou seja, um curto-circuito. Um componente especial, o buffer controlado, permite fazer esse tipo de ligao, o que simplifica muito o desenho de circuitos. Diversas sadas podem ser conectadas a um nico cabo se essas conexes passarem por um buffer controlado. Este cabo compartilhado recebe o nome de barramento. Todo buffer controlado tem, como o prprio nome indica, um pino de controle que abre ou fecha a conexo com o barramento. O projetista de um circuito deve cuidar para que, a qualquer instante, no mximo um dentre todos os buffer controlados ligados a um mesmo barramento esteja aberto.

Circuitos Sequenciais
Colocar 7 no registrador A Comentrio Colocar 7 (em binrio, 111) na entrada In Colocar o valor de In no barramento Copiar o valor do barramento no registrador A Zerar o clock do registrador A Liberar o barramento
Colocar 3 no registrador B Comentrio Colocar 3 (em binrio, 11) na entrada In Colocar o valor de In no barramento Colocar o valor do barramento no registrador B Zerar o clock do registrador B Liberar o barramento

89

Passo 1 2 3 4 5
Passo 1 2 3 4 5
Passo 1 2 3 4

Sinal In = 7 In_Bus = 1 A_Clk = 1 A_Clk = 0 In_Bus = 0


Sinal In =3 In_Bus = 1 B_Clk = 1 B_Clk = 0 In_Bus = 0

Colocar no registrador C o contedo do registrador A Sinal Comentrio A_Bus = 1 Colocar o valor do registrador A no barramento C_Clk = 1 Copiar o valor do barramento no registrador C C_Clk = 0 Zerar o clock do registrador C A_Bus = 0 Liberar o barramento

Figura 129 : Exemplos de fluxos de dados realizveis pelo circuito da Figura 128.

O circuito da Figura 128 permite que um dado na entrada In seja copiado por qualquer dos registradores A, B ou C, e permite tambm que o valor em qualquer registrador seja copiado por qualquer um dos outros registradores. Estes fluxos so controlados pelos sinais de clock dos registradores e de controle dos buffers controlados. Dados so transferidos de um ponto para outro ligando e desligando esses sinais em uma sequncia apropriada para a transferncia desejada. A Figura 129 mostra exemplos de sequncias de sinais que devem ser aplicados ao circuito para que ocorram transferncias de dados especficas. Os sinais devem ser aplicados na sequncia dos passos. Na figura usamos a notao (por exemplo) B_Clk = 1 para indicar que o valor 1 deve ser aplicado entrada B_Clk pelo operador Logisim, e In = 3 para dizer que o valor 3 (em binrio, 11) deve ser aplicado entrada In.

3.3 Memrias
O Logisim oferece memrias RAM (Random Access Memory) e ROM (Read Only Memory) como componentes de sua biblioteca Memory. Memrias armazenam informaes como conjuntos de bits chamados palavras; cada palavra possui um endereo na memria. Uma memria tem como atributos sua largura de dados, isto , o nmero de bits em cada palavra da memria, e a largura do endereo. Com bits de endereo uma memria tem no mximo 2 palavras. No Logisim, a largura de bits do endereo determina tambm o tamanho da memria: uma memria de bits de endereo tem exatamente 2 palavras.

Circuitos Sequenciais

90

Memory Address Register

Entrada e tambm sada de dados

Na subida, copia D na posio A Controle de posse do barramento

Figura 130: Uma memria RAM do Logisim em um arranjo com registradores e barramento

A Figura 130 mostra um arranjo de uma memria RAM e de registradores em torno de um barramento. As operaes de leitura e escrita se fazem com uma nica palavra da memria, determinada pelo valor aplicado entrada A: para escritas, o sinal RAM_Clk funciona como o clock de um registrador: na subida de 0 para 1, o valor presente na entrada D copiado para a posio de memria endereada pela entrada A, o que, no arranjo da Figura 130, o valor armazenado no registrador MAR, o Memory Addres Register; para leituras, o sinal RAM_Bus funciona como um buffer controlado conectado sada de um registrador: enquando seu valor for 1, a memria coloca no barramento o contedo da palavra endereada pela entrada A.
Passo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Escrever 9 na posio de memria 15 Comentrio Colocar 15 (em binrio, 1111) na entrada Input Copiar no registrador In a entrada Input Zerar o clock do registrador In Colocar o valor de In no barramento Copiar o valor do barramento no registrador MAR (e MAR_Clk = 1 tambm na entrada A da RAM) MAR_Clk = 0 Zerar o clock do registrador MAR In_Bus = 0 Liberar o barramento Input = 9 Colocar 9 (em binrio, 1001) na entrada Input In_Clk = 1 Copiar no registrador In a entrada Input In_Clk = 0 Zerar o clock do registrador In In_Bus = 1 Colocar o valor de In no barramento RAM_Clk = 1 Copiar o valor do barramento no endereo A da RAM RAM_Clk = 0 Zerar o clock da memria In_Bus = 0 Liberar o barramento Sinal Input = 15 In_Clk = 1 In_Clk = 0 In_Bus = 1

Figura 131: Um fluxo de dados realizvel pelo circuito da Figura 130

Exemplos de fluxos de dados realizveis com o circuito da Figura 130 so mostrados na Figura 131 e na Figura 132.

Circuitos Sequenciais
Copiar o contedo da posio 15 da memria para o registrador Out Passo Sinal Comentrio 1 Input = 15 Colocar 15 (em binrio, 1111) na entrada Input 2 In_Clk = 1 Copiar no registrador In a entrada Input 3 In_Clk = 0 Zerar o clock do registrador In 4 In_Bus = 1 Colocar o valor de In no barramento Copiar o valor do barramento no registrador MAR (e 5 MAR_Clk = 1 tambm na entrada A da RAM) 6 MAR_Clk = 0 Zerar o clock do registrador MAR 7 In_Bus = 0 Liberar o barramento Colocar o valor da posio A da memria no 8 RAM_Bus = 1 barramento 9 Out_Clk = 1 Copiar o valor do barramento no registrador Out 10 Out_Clk = 0 Zerar valor do clock do registrador Out 11 RAM_Bus = 0 Liberar o barramento Figura 132: Outro exemplo de fluxo de dados realizvel com o circuito da Figura 130

91

3.4 Acumuladores e Loops

Registrador Acumulador

Circuito Soma (combinatrio)

Figura 133: Um registrador acumulador

Um registrador pode ser usado como um acumulador, como mostrado na Figura 133. Neste arranjo, a entrada do acumulador alimentada por um circuito combinatrio que tipicamente realiza operaes aritmticas ou lgicas, e a sada do acumulador realimenta o circuito combinatrio, isto , a sada do acumulador uma das entradas do circuito combinatrio.

Este arranjo permite, por exemplo, somar 10 nmeros, seqenciando as somas ao longo do tempo. Permitiria tambm, a uma pessoa que vivesse o tempo suficiente, somar um milho de parcelas.

Circuitos Sequenciais
Calcular 2+7+4 e colocar o resultado no registrador Out Sinal Comentrio ACC_Clr = 1 Zerar o acumulador ACC_Clr = 0 In = 2 Colocar 2 (em binrio, 10) na entrada In Colocar o valor de In no barramento (a outra entrada In_Bus = 1 do somador tem o valor do acumulador, que 0) ACC_Clk = 1 Copiar o valor da sada do somador no acumulador ACC_Clk = 0 Zerar o clock do acumulador Colocar 7 (em binrio, 111) na entrada In (e tambm no barramento). A sada do somador contm a soma do valor no barramento com o valor no acumulador ACC_Clk = 1 Copiar o valor da sada do somador no acumulador ACC_Clk = 0 Zerar o clock do acumulador In = 4 Colocar 4 (em binrio, 100) na entrada In ACC_Clk = 1 Copiar o valor da sada do somador no acumulador ACC_Clk = 0 Zerar o clock do acumulador In_Bus = 0 Liberar o barramento ACC_Bus = 1 Colocar o valor do acumulador no barramento Out_Clk = 1 Copiar o valor do barramento no registrador Out Out_Clk = 0 Zerar o clock do registrador Out ACC_Bus = 0 Liberar o barramento In = 7

92

Passo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

Figura 134: Exemplo de fluxo de dados realizvel pelo circuito da Figura 133

A Figura 134 mostra um exemplo de uso de um acumulador para a soma de trs parcelas.

3.5 Uma Calculadora

Figura 135: Uma calculadora

Circuitos Sequenciais

93

A Figura 135 mostra um circuito uma calculadora com diversos componentes ligados a um barramento de 16 bits: Registradores In e Out, ligados tambm a entradas e sadas de 16 bits Um registrador de dados, o DR; Uma memria principal com 32K palavras de 16 bits, tambm com 16 bits de endereo; Uma unidade lgico-aritmtica, que um circuito combinatrio com duas entradas, uma ligada ao barramento e outra sada do acumulador. A ALU (Arithmetic and Logical Unit) capaz de realizar somas, subtraes e comparaes entre suas duas entradas. (Outras operaes que uma ALU poderia fazer incluem operaes lgicas AND, OR e NOT e de deslocamento (shift) de bits.) Um registrador acumulador ACC, alimentado pela sada de resultado de operao da unidade lgico-aritmtica; Um registrador de resultado de comparao Compare, tambm alimentado pela ALU. Este registrador armazena 3 bits, e sua sada est ligada a leds com os rtulos Bus_GT_ACC, Bus_EQ_ACC e Bus_LT_ACC. GT vem de Greater Than, EQ de EQual, e LT de Less Than.

Temos ainda o registrador MAR, que alimenta a entrada de endereo da memria principal, e que alimentado pelo barramento. A biblioteca Entrada/Sada do Logisim oferece leds, pequenas lmpadas que foram acrescentadas ao circuito somente para acompanhamento visual do registrador Compare. Cada registrador, assim como a memria principal, tem um sinal de clock; cada sada para o barramento tem um sinal que controla a posse do barramento. As rotas de dados de uma calculadora como a da Figura 135 permitem controlar diversos fluxos de dados diversas computaes envolvendo a memria RAM, as entradas e sadas, o acumulador e os registradores de dados e de endereos. O controle do fluxo de dados feito pelo usurio Logisim, que se encarrega de: mudar de 0 para 1 ou de 1 para 0 os sinais de controle de posse de barramentos e de cpia de registradores, na seqncia adequada ao efeito desejado, e de fornecer valores atravs do registrador Input.

Vamos usar a calculadora para resolver um problema simples de transformao de informao: queremos somar os contedos das posies 1 e 2 da memria, e colocar o resultado na posio 3. Podemos fazer isso atravs das etapas: 1. Carregar no acumulador o contedo da posio 1 da RAM 2. Somar ao acumulador o contedo da posio 2 da RAM 3. Armazenar o contedo do acumulador na posio 3 da RAM. Na Figura 136 e na Figura 137 esto mostradas tabelas com uma sequncia de aes a serem executadas por um operador Logisim. Essas aes so sinais de controle a serem aplicados calculadora ou, em destaque, entradas de valores literais necessrios para essa computao. A notao utilizada a seguinte: ACC_Clear=1, por exemplo, significa fazer a entrada ACC_Clear igual a 1; Input=3 significa colocar 3 (em binrio, 11) na entrada Input. Essas tabelas de aes funcionam como um programa, a ser executado por uma pessoa utilizando a calculadora.

Circuitos Sequenciais
Sinal ACC_Clear = 1 ACC_Clear = 0 Input = 1 In_Clk = 1 In_Clk = 0 In_Bus = 1 MAR_Clk = 1 MAR_Clk = 0 In_Bus = 0 RAM_Bus = 1 ACC_Clk = 1 ACC_Clk = 0 RAM_Bus = 0 Comentrios

94

Input = 2 In_Clk = 1 In Clk = 0 In_Bus = 1 Carrega no acumulador o MAR_Clk = 1 Soma ao acumulador o contedo da posio 1 da RAM MAR_Clk = 0 contedo da posio 2 da RAM In_Bus = 0 RAM_Bus = 1 ACC_Clk = 1 ACC_Clk = 0 RAM_Bus = 0 Figura 136: Sinais de controle e, em destaque, entrada dos valores literais 1 e 2 para as etapas 1 e 2

Input = 3 In_Clk = 1 In_Clk = 0 In_Bus = 1 MAR_Clk = 1 MAR_Clk = 0 In_Bus = 0 ACC_Bus = 1 RAM_Clk = 1 RAM_Clk = 0 ACC_Bus = 0

Armazena o contedo do acumulador na posio 3 da RAM

Figura 137: Sinais de controle e entrada de valor literal 3 para a etapa 3

O momento de escrita do programa diferente do momento de sua execuo, e podemos distinguir entre valores que so conhecidos no momento da programao, como os endereos 1, 2 e 3, e valores que s sero conhecidos no momento da execuo do programa, como os contedos das posies 1 e 2 da memria. Ns chamamos os valores j conhecidos no momento da programao de valores literais, ou simplesmente literais.

3.6 Clocks
Ns vamos agora introduzir um novo tipo de circuito digital, completando os ingredientes que, como veremos no prximo mdulo, nos permitiro transformar esta calculadora em um processador, isto , em um circuito digital capaz de, automaticamente, executar as operaes prescritas em um programa. O ponto a resolver o clicar automatizado de botes, isto , a emisso de sinais de controle seqenciados no tempo sem interveno humana; para isso vamos precisar de um novo tipo de circuito. O motor, o propulsor de qualquer circuito digital um oscilador, ou clock. Um clock um dispositivo cuja sada oscila entre 0 e 1 em uma freqncia conhecida. Um computador de 1 GHz (1 Giga Hertz) utiliza um clock cuja sada varia entre 0 e 1, um bilho de vezes por segundo. O Logisim oferece clocks simulados, para os quais o usurio pode escolher a freqncia de oscilao, como mostra a Figura 138.

Circuitos Sequenciais

95

Figura 138: Um clock no Logisim, com o menu de escolha de freqncia

A partir do sinal bsico fornecido por um clock, circuitos como registradores circulares podem fornecer outros sinais, que podem ser usados para coordenar ao longo do tempo o fluxo de dados em um circuito.

Figura 139: Um registrador circular

A Figura 139 mostra um registrador circular formado por trs flip-flops tipo D alimentados por um clock. O cabeamento tal que a sada do FF t0 est ligada entrada D do FF t1, a sada do FF t1 entrada do FF t2, e a sada do FF t2 est ligada entrada do FF t0, em um arranjo circular. O registrador inicializado atravs do pino Reset, que coloca 1 no flip-flop t0, e 0 nos demais. A cada subida do clock cada FF copia a sua entrada, o que faz com que o 1 inicialmente armazenado no FF t0 passe para o FF t1, depois para o t2, retornando ento ao FF t0.

Circuitos Sequenciais

96

t2

t1
t0

Clock Reset

Figura 140: Carta de tempo para o registrador circular da Figura 139

A Figura 140 mostra a evoluo temporal de um registrador circular. importante observar que um registrador circular pode ter quantos flip-flops se queira e que, com isso, conseguimos obter sinais distribudos no tempo na forma como desejarmos. Temos agora todos os ingredientes necessrios para a construo de um processador, o que faremos no prximo mdulo.

4 - Processadores

98

4 Processadores
4.1 Programa Armazenado
Um processador um circuito digital com comportamento flexvel, comandado por uma coisa que chamamos de programa. Um programa produzido por um ser humano, que deseja resolver um problema de transformao de informao. Trocando-se o programa, troca-se o comportamento do processador. Isso no deve envolver modificaes no circuito, pois a idia que essa troca de programa seja uma operao de fcil realizao. Se isso o que queremos, um programa s pode ser, em seu formato final, informao codificada em bits, que deve ser carregada em alguma memria para sua execuo. Para eliminar a necessidade de interveno humana durante a execuo do programa, uma unidade de controle deve ser adicionada calculadora. Ao executar um programa, a unidade de controle deve se encarregar das tarefas executadas na calculadora pelo operador Logisim, que so: emitir sinais de controle, e fornecer valores literais.

Vamos construir uma primeira unidade de controle usando as seguintes idias: para sua execuo, o programa deve ficar armazenado como uma seqncia de palavras em uma memria RAM; por razes que veremos depois, chamamos cada palavra desses programas de micro-instruo; a cada sinal de controle da calculadora deve corresponder um bit nas microinstrues; a unidade de controle implementa um ciclo de leitura em seqncia de microinstrues da memria com o programa, manipulando adequadamente a entrada de endereo da memria; em cada ciclo, os bits de cada palavra lida so encaminhados para as sadas da unidade de controle, que so ligadas aos pontos de controle da (ex-) calculadora.

Micro-instruo
23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Endereo

Sinais
In_bus In_Clk MAR_Clk RAM_Bus RAM_Clk DR_Bus DR_Clk Subtract Out_Clk Compare_Clk ACC_Bus ACC_Clk ACC_Clear

Clicks Equivalentes

Efeito

0 1 2 3 4

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 1 1 0 0

0 0 0 0 0

0 0 1 0 0

0 0 0 0 0

0 0 0 0 1

0 0 0 1 1

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

1 0 0 0 0

ACC_Clear = 1 ACC_Clear = 0; In_Bus = 1 MAR_Clk = 1 In_Bus = 0; MAR_Clk = 0; DR_Bus = 1 RAM_Clk = 1

ACC = 0 Bus = In MAR = Bus Bus = DR RAM = Bus

Microinstrues
Figura 141: Codificao de sinais de controle em micro-instrues

A Figura 141 mostra como podemos especificar micro-instrues por meio de uma tabela onde cada coluna da parte mais esquerda corresponde a um dos sinais de controle do circuito da

4 - Processadores

99

Figura 135. Cada linha da tabela corresponde a uma micro-instruo, e as micro-instrues sero executadas sequencialmente pela unidade de controle. As duas colunas mais direita tm informaes para consumo humano: os clicks que o operador Logisim deveria realizar, e o efeito sobre o estado do circuito. Repare que desta forma possvel ligar ou desligar mais de um boto ao mesmo tempo.

Contador de Programa armazena o endereo da prxima micro-instruo a ser executada

Memria de Programa

Figura 142: Circuito para gerao automtica de sinais de controle segundo um programa armazenado em uma memria RAM

Ns vamos agora mostrar um circuito que gera automaticamente sinais de controle, ignorando por enquanto o problema do fornecimento de literais. No circuito da Figura 142 ns vemos: uma memria RAM onde fica armazenado um programa (ns veremos mais tarde como colocar um programa na memria), sadas de sinais de controle, ligadas diretamente sada da memria de programa, e um contador de programa, denominao que se d a registradores com a funo de controlar o endereo aplicado a memrias de programa, e que contm ou o endereo da instruo em execuo, ou o endereo da prxima instruo a ser executada.

Por uma questo de uniformidade com os outros processadores que examinaremos aqui, a memria de programa tem palavras de 24 bits, o que faz com que os bits de 12 a 23 no estejam sendo utilizados. O contador de programa PC (Program Counter) tem o seu valor incrementado de 1 a cada subida do clock, o que faz com que a sada de dados da memria exponha em sucesso as micro-instrues. Como cada micro-instruo determina o valor dos sinais de sada, ns temos o que queramos: a gerao automtica de sinais de controle, guiada por um programa carregado na memria.

4 - Processadores

100

Figura 143: Uma caixa de msica 38; o cilindro tem o papel da memria com um programa; as salincias no cilindro tm papel anlogo ao dos bits ligados em uma micro-instruo

O comportamento deste circuito lembra o de uma caixa de msica como a que mostra a Figura 143 (no deixe de ver tambm o vdeo no YouTube; muito bom), onde o cilindro tem o papel de uma memria onde est gravado um programa..

Soma 1

Registrador

Figura 144: Um contador de programa simples

A Figura 144 mostra o circuito do contador de programa, que um registrador cuja sada uma das parcelas de um circuito de soma , cuja sada realimenta a entrada do registrador. A outra parcela da soma sempre igual a 1, o que produz o efeito que desejamos para a execuo das micro-instrues em sequncia: a cada subida do clock, o valor do PC incrementado de 1. O circuito possui tambm uma entrada Reset que zera o PC.

38

bigbluesky2002, YouTube - Swiss Antique Music Box, acessado 1 de abril de 2011, http://www.youtube.com/watch?v=-tzWt1X3oOg&p=66A384A130B0DCE4.

4 - Processadores

101

4.2 CPU-0: Um Primeiro Processador


Dominado o problema da emisso dos sinais de controle, vamos agora ver como eliminar a necessidade de interveno do operador Logisim tambm na entrada de valores literais (endereos da memria, valores a serem adicionados ou carregados no acumulador, etc.). Ns queremos agora permitir que literais possam ser especificados no programa, e que seus valores sejam fornecidos pela unidade de controle (ex-) calculadora nos momentos adequados.

Sinal Adicional coloca Operando no Barramento Bit 23 indica se a palavra codifica um operando

Operando nos 16 bits menos significativos = 2

Figura 145: Codificao de operandos em micro-instrues

A Figura 145 mostra uma forma de se codificar valores literais em micro-instrues. Por motivos de ordem prtica, ns adotamos micro-instrues de 24 bits. Para indicar que uma micro-instruo codifica um valor literal, ns vamos utilizar o bit 23, o mais significativo. Se este bit for igual a 0, os bits restantes so interpretados como sinais de controle; se for igual a 1, os 16 bits menos significativos so a codificao em binrio de um valor literal (o barramento da calculadora tem 16 bits de largura). A unidade de controle dever ter uma sada com o valor do literal, ligada ao barramento da calculadora, e utilizando, como todas as outras ligaes de sada para o barramento, um buffer controlado para evitar conflitos. Este buffer controlado comandado por um sinal, que deve ser adicionado aos sinais j emitidos pela unidade de controle.

4 - Processadores

102

Figura 146: CPU-0: nosso primeiro processador

J temos agora condies de mostrar o nosso primeiro processador, capaz de executar microinstrues em sequncia, com sinais de controle e valores literais fornecidos por uma unidade de controle. A Figura 146 mostra o circuito principal da CPU-0, nome que demos a este processador. Para compreend-lo, voc deve primeiramente reparar que podemos dividi-lo em duas partes. Na metade superior voc deve reconhecer a nossa calculadora, onde todos os sinais de controle foram ligados sada da unidade de controle (o bloquinho escrito Ctrl), que fica na metade inferior do circuito. Voc deve ainda reparar que a unidade de controle tambm tem uma sada ligada ao barramento da calculadora; por esta sada que passam os literais especificados nas microinstrues.

4 - Processadores

103

fornece tempos para atualizaes: t0: PC t1: Sinais ou Literal

Sada de Literal

Sada de Sinais

Micro-instruo corrente

Acompanhamento visual

Figura 147: Unidade de controle da CPU-0

A Figura 147 mostra os detalhes internos da unidade de controle da CPU-0. Voc deve reparar que a unidade de controle possui: registradores de sinais e de literal, que armazenam os bits fornecidos pelas sadas de mesmo nome; uma memria que armazena o programa; a micro-instruo corrente o contedo da posio de endereo PC, que colocada na sada D da memria; um circuito de temporizao T, similar ao que j vimos na Figura 139, e que ao longo do tempo fornece os sinais t0 e t1 conforme mostrado na Figura 140; alguns LEDs sem participao na lgica do circuito, mas que ajudam no acompanhamento visual da simulao.

atravs dos sinais fornecidos pelo circuito de temporizao que o ciclo de execuo de microinstrues implantado na CPU-0: o sinal t0 atualiza o valor do PC; o sinal t1 faz com que ou o registrador Sinais, ou o registrador Oper, copie sua entrada, com a escolha dentre estes dois sendo determinada pelo bit 23 da microinstruo corrente.

Muito bem, j temos um circuito que executa programas formados por micro-instrues, onde cada micro-instruo codifica sinais de controle ou literais, sem necessidade de interveno humana na execuo. Mas temos ainda que resolver dois problemas: como construir um programa, e como fazer para colocar este programa na memria de micro-instrues da CPU0.

4 - Processadores
Micro-instruo
23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

104

Efeito Da microAcumulado instruo


Carrega no acumulador o contedo da posio 1 da RAM

Endereo

Sinais
Literal? Literal_Bus In_Dbus In_Clk MAR_Clk RAM_Bus RAM_Clk DR_Bus DR_Clk Subtract Out_Clk Compare_Clk ACC_Bus ACC_Clk ACC_Clear
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

1 ACC = 0 1 Literal = 1 Bus = Literal MAR = Bus Bus = RAM ACC = ACC + Bus Literal = 2 Bus = Literal MAR = Bus Bus = RAM ACC = ACC + Bus 1 Literal = 3 Bus = Literal MAR = Bus Bus = ACC RAM = Bus

Soma ao acumulador o contedo da posio 2 da RAM

Armazena o contedo do acumulador na posio 3 da RAM

Figura 148: Construindo um programa para a CPU-0

Para programar a CPU-0 ns podemos usar uma tabela como a da Figura 148, cujas colunas se dividem em 3 agrupamentos: Endereo, que indica em qual posio da memria de programa a micro-instruo deve ser armazenada, Micro-instruo, onde so colocados pelo programador os 24 bits que compem a micro-instruo propriamente dita (na figura posies com valor zero esto em branco, para no poluir visualmente a tabela), e Efeito, que contm informaes para consumo humano, indicando tanto o efeito de cada micro-instruo como o efeito acumulado de grupos de micro-instrues.

Os bits marcados no agrupamento de micro-instrues constituem uma imagem que deve ser carregada na memria de programa da CPU-0. O programa da Figura 148 corresponde exatamente aos sinais de controle e entradas de operandos mostrados na Figura 136 e na Figura 137; sua execuo tem portanto o mesmo efeito: somar os contedos das posies 1 e 2 da memria, e colocar o resultado na posio 3. Construda a tabela-programa, os bits das micro-instrues devem ser armazenados em alguma mdia, e carregados na memria de programa do processador. Nos computadores atuais a carga de programas feita por um outro programa, chamado de carregador ou loader. Sim, mas como que um loader vai parar na memria do computador? Nos computadores atuais, um loader primitivo gravado pelo fabricante em uma memria ROM ( Read Only Memory), e executado no momento em que o computador ligado, constituindo a primeira etapa de um procedimento que tem o nome de bootstrap. Usando um disco magntico (tipicamente), o loader primitivo carrega um outro loader, mais sofisticado, que por sua vez carrega outro mais sofisticado ainda, e isso termina com a carga do sistema operacional. O uso normal de programas utiliza um loader do sistema operacional.

4 - Processadores

105

Figura 149: Painel de um PDP11/70, de 197539

Nem sempre foi assim. Quando ainda no existiam memrias ROM, o loader primitivo era carregado palavra por palavra, atravs do painel do computador. Como voc pode ver na Figura 149, o painel continha uma srie de chaves cujo posicionamento ligava ou desligava um bit, e botes para carregar o registrador de endereo ou o contedo de uma posio de memria com os bits definidos pelas chaves. No era necessrio fazer isso a cada vez que se ligava o computador: a memria principal daquele tempo utilizava ncleos de ferrite, e no era voltil. Reservavam-se algumas posies de memria para conter o loader, e a carga atravs do painel s era necessria quando, por um erro de programao, algum escrevia sobre essas posies da memria.

Figura 150: Arquivo com mapa de memria usado pelo Logisim

Aqui ns no trabalhamos com memrias reais, e sim com memrias simuladas pelo Logisim. Isso nos permite escrever diretamente valores para posies de memria, ou ler de um
39

File:Pdp-11-70-panel.jpg - Wikipedia, the free encyclopedia, acessado 2 de setembro de 2011, http://en.wikipedia.org/wiki/File:Pdp-11-70-panel.jpg.

4 - Processadores

106

arquivo um mapa da memria (para ter acesso a essas operaes, clique com o boto direito do mouse sobre a memria). A Figura 150 mostra o formato de um arquivo com a codificao em hexadecimal do programa da Figura 148 e a memria de programa Logisim aps a carga deste arquivo. No site do curso voc ir encontrar planilhas que auxiliam na produo de arquivos-programas em hexadecimal.

4.3 CPU-1: Processador com Instrues de Desvio


Suponha agora que queremos construir para a CPU-0 um programa que some os contedos das posies 1, 2, 3, 4 e 5 da memria principal, e coloque o resultado na posio 6. No difcil: basta acrescentar ao programa mais passos de somas ao acumulador, como ilustra a Figura 151.

Soma de 2 parcelas
Sinais
Oper->Bus In->Dbus In_Clk MAR_Clk RAM_Bus RAM_Clk DR->Bus DR_Clk Subtract Out_Clk Compare_Clk ACC->Bus ACC_Clk ACC_Clear Operando?
Operando?

Soma de 5 parcelas
Sinais
Oper->Bus In->Dbus In_Clk MAR_Clk RAM_Bus RAM_Clk DR->Bus DR_Clk Subtract Out_Clk Compare_Clk ACC->Bus ACC_Clk ACC_Clear
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

1 1

Figura 151: Programas para a CPU-0 que somam 2 e 5 parcelas

Ns sabamos que era possvel realizar computaes arbitrariamente complicadas com a nossa calculadora, aplicando manualmente sinais de controle, e entrando tambm manualmente com os operandos necessrios. Com a CPU-0, ns mostramos que possvel automatizar essas operaes, com o uso de uma unidade de controle impulsionada por um clock. Mas o exemplo da soma de 5 parcelas nos mostra um problema: na CPU-0, um programa cresce de tamanho com o nmero de operaes que realiza. Qual seria o tamanho de um programa que soma um milho de parcelas? Para conseguir escrever programas cujo tamanho no cresa com o nmero de operaes que sua execuo realiza, precisamos alterar nosso modelo de execuo seqencial de microinstrues. Ns vamos agora apresentar um outro processador, a CPU-1, que possui uma micro-instruo especial que desvia o fluxo de execuo para um endereo designado na memria de programa. O ciclo de leitura e execuo de micro-instrues deve ser modificado em funo disso, pois a prxima micro-instruo a ser executada nem sempre a que est armazenada no endereo consecutivo da memria de programa.

4 - Processadores

107

Bit 23: Literal? Bit 22: Desvio?

Micro-instruo de desvio para a posio 4 na memria de programa

Figura 152: Formato de micro-instrues que contempla instrues de desvio

A Figura 152 mostra como as micro-instrues so codificadas na CPU-1: Se o bit 23 (o mais significativo) for igual a 1, a micro-instruo de desvio. A prxima micro-instruo a ser executada aquela armazenada no endereo codificado nos 16 bits menos significativos. Se o bit 22 for igual a 1, a micro-instruo contm um valor literal, codificado (como na CPU-0) nos 16 bits menos significativos. Se os bits 22 e 23 forem iguais a zero, temos uma micro-instruo de sinais; Os bits 22 e 23 nunca devem ser ambos iguais a 1 em uma micro-instruo.

Bit 22: deciso de desvio

Endereo para desvio

Figura 153: Unidade de controle da CPU-1, com destaque para a conexo do registrador de operando com o contador de programa e para a deciso de desvio, indicada pelo bit 22 da micro-instruo corrente

4 - Processadores

108

Para alterar o ciclo de micro-instruo ns temos que modificar a unidade de controle e o contador de programa da CPU-0. Na Figura 153 ns vemos a unidade de controle da CPU-1, onde voc deve atentar para as seguintes modificaes: O contador de programa tem duas entradas adicionais. Uma delas est conectada ao registrador Oper, e recebe o endereo para um possvel desvio. A outra entrada est conectada ao bit 23 do registrador de micro-instruo que, como vimos, indica se a micro-instruo corrente de desvio. O registrador Oper usado para armazenar o endereo de desvio. O registrador Sinais zerado se o bit 22 ou o bit 23 da micro-instruo corrente for igual a 0.

Endereo de Desvio

Deciso sobre o prximo valor do PC

Figura 154: O contador de programa da CPU-1, com possibilidade de imposio de um novo endereo arbitrrio

A Figura 154 mostra o novo contador de programa, onde voc deve reparar que a entrada do registrador de endereo est conectada sada de um multiplexador. Este multiplexador encaminha para a entrada ou bem o valor corrente do PC acrescido de 1 (fornecido pela sada do somador), quando a entrada Desvio igual a 0, ou ento o valor da entrada D, quando a entrada Desvio igual a 1.

Figura 155: Um programa para a CPU-1

4 - Processadores

109

Na Figura 155 ns vemos uma tabela com um programa para a CPU-1, cujo efeito muito simples: o programa usa o acumulador para contar 1, 2, 3, ... indefinidamente. Para executar este programa no Logisim as etapas so as mesmas: as micro-instrues devem ser gravadas em um arquivo, codificadas em hexadecimal, uma em cada linha. Este arquivo deve ser carregado na memria de programa na unidade de controle da CPU-1.

4.4 CPU-2: Processador com Instrues de Desvio Condicional


Com a micro-instruo de desvio da CPU-1 ns conseguimos construir programas que prescrevem a repetio de aes por um processador e, com isso, desvincular o tamanho de um programa do nmero de operaes realizadas em sua execuo. Este um resultado muito importante, pois programas so feitos por ns, humanos, que queremos trabalhar pouco, e so executados por computadores, que no se importam de trabalhar muito. Mas como fazer para interromper as repeties? Afinal, um loop precisa parar. Ns queremos poder construir programas que resolvam problemas como somar os contedos das posies de memria com endereos entre 100 e 200, ou encontrar o menor valor entre os contedos das posies de memria com endereos entre 1000 e 1.000.000, que certamente envolvem loops, mas que devem ser interrompidos ao se atingir os limites das operaes desejadas. Este problema resolvido por micro-instrues de desvio condicional, que provocam desvios no fluxo de execuo somente quando o resultado de comparaes satisfizer uma condio (maior, igual, menor, maior ou igual, etc.).

Desviar para o endereo 10 se Bus > ACC

Figura 156: Codificao de micro-instrues de desvio condicional

Na Figura 156 voc pode ver a codificao de micro-instrues que iremos adotar para um novo processador, a CPU-2. Nessa codificao, o bit 22 indica se a micro-instruo de desvio; o bit 23, como na CPU-1, indica que a micro-instruo contm um valor literal; os bits 21, 20 e 19 so usados nas micro-instrues de desvio, e especificam as condies em que o desvio deve ser efetivamente realizado, em funo do valor corrente do registrador de comparao. Se, por exemplo, tivermos uma micro-

4 - Processadores

110

instruo de desvio com os bits 21 e 20 iguais a 1, e o bit 19 igual a zero, na execuo desta micro-instruo o desvio ocorrer somente se o registrador de comparao estiver seja com a sada D<ACC ligada, seja com a sada D=ACC ligada. Um desvio incondicional pode ser obtido colocando estes 3 bits iguais a 1.

Registrador Compare Unidade de Controle

Figura 157: Parte da CPU-1, destacando a alimentao da sada do registrador de comparao como entrada adicional da unidade de controle

Na Figura 157 voc pode ver que a sada do registrador de comparao alimenta agora a unidade de controle, fornecendo a informao necessria para as decises de desvio condicional.

Lgica para deciso de desvio: Condies na micro-instruo coincidem com o status do registrador de comparao?

Figura 158: A unidade de controle da CPU-2, com destaque para a lgica de desvio

4 - Processadores Quanto unidade de controle, as novidades so (veja a Figura 158):

111

temos uma entrada adicional que, como j dissemos, alimentada pelos trs bits do registrador de comparao da calculadora esses trs bits que vm do registrador de comparao so confrontados com os trs bits (bits 21, 20 e 19) da micro-instruo que, conforme a Figura 156, especificam a condio de desvio . Essa confrontao dada pela expresso booleana Desvio = (b21.D<ACC) + (b20.D=ACC) + (b19.D>ACC) que coloca o valor 1 na entrada Desvio do PC (isto , determina a realizao do desvio) quando pelo menos uma das condies de desvio atendida pelo estado do registrador de comparao.

Usando estas micro-instrues de desvio condicional, ns pudemos desenvolver o programa da Figura 159, que tambm ir usar o acumulador para contar 1, 2, 3, ..., mas que interrompe a contagem quando o valor do acumulador atingir um valor colocado antes do incio da simulao na entrada In.

Figura 159: Um programa para a CPU-2

Este programa inicia armazenando o valor encontrado na entrada Input (e que deve ser colocado ali antes do incio da simulao) na posio 3 da memria. Em seguida acumulador inicializado com o valor 1. Segue-se um loop de soma e de comparao, que inclui uma microinstruo de desvio condicional.

4.5 CPUs Reais: Instrues e Programao em Assembler


Com a CPU-2 ns conseguimos construir programas que prescrevem operaes repetitivas para execuo por um processador, e conseguimos tambm, com desvios condicionais, interromper em momentos adequados essas repeties. Isto o suficiente para que, com meios de armazenamento externo suficientes, se consiga fazer qualquer computao, mesmo aquelas realizadas por supercomputadores. Entretanto, a forma de se programar, que na verdade se reduz a acender e apagar diretamente sinais de controle, torna difcil a construo de programas para a soluo de problemas mais complexos de transformao de informao. AS CPUs reais tm caractersticas que as distinguem das que vimos aqui, que foram projetadas com propsitos pedaggicos:

4 - Processadores programas, em sua forma de carga na memria do processador, so formados por instrues; o efeito de cada instruo obtido pela execuo de vrias micro-instrues, e correspondem aproximadamente aos textos nas colunas Efeito Acumulado dos programas que fizemos para as CPUs anteriores; valores literais so codificados nas instrues; no existe uma memria para programas e outra para dados; uma nica memria RAM abriga dados e programa; existem circuitos para sincronizao de operaes de entrada e sada; o processador executa um ciclo de leitura e execuo de instrues; a programao pode ser feita em linguagem de montagem, o que representa um grande avano com relao programao por sinais de controle.

112

Instruo Efeito LOAD Carrega o operando no acumulador Armazena o valor do acumulador no endereo de STORE memria especificado pelo operando Soma o valor do operando ao valor do acumulador, ADD deixando o resultado no acumulador Compara o valor do operando com o valor do COMPARE acumulador Desvio incondicional para o endereo especificado JMP pelo operando Desvio para o endereo especificado pelo operando JMPEQ se o resultado da ltima comparao for "iguais" Desvio para o endereo especificado pelo operando JMPLT se o resultado da ltima comparao for "menor que"
Figura 160: Instrues Tpicas de uma CPU simples

A Figura 160 mostra alguns exemplos de instrues tpicas de CPUs simples. Como voc pode reparar comparando com a Figura 159, cada instruo corresponde aproximadamente ao efeito acumulado de uma sequncia de micro-instrues. O processo de programao em assembler consiste em preencher uma tabela usando no os cdigos das instrues, mas seus mnemnicos, e tambm usando nomes (labels) dados a posies de memria, e no os endereos efetivos. Isso torna o programa muito mais fcil de se escrever e se ler. Os bits de cada instruo so depois obtidos por uma substituio cuidadosa dos mnemnicos e dos nomes de posies de memria por seus cdigos em bits, em um processo que chamamos de montagem da instruo.

4 - Processadores
Instruction

113

Address10

Address16

Operand

1 1 1 1 LOOP 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

00 01 02 03 04

LOAD STORE LOAD STORE LOAD

Mode

Label

Comentrios

Size

0 0 0 0 1

05 ADD 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 STORE LOAD ADD STORE COMPARE JMPLT JMP OUTPUT HALT

FINISH X

XEND SUM P

Zera o acumulador Coloca 0 em SUM Carrega o endereo X no acumulador Coloca o endereo X em P Carrega o contedo de SUM no acumulador Soma o contedo da posio de memria cujo 2 P endereo P ao acumulador 0 SUM Coloca o resultado na posio SUM 1 P Carrega o contedo de P 0 1 Soma 1 0 P Coloca o resultado em P 0 XEND Compara XEND com o acumulador 0 FINISH Se for menor, desvia para FINISH 0 LOOP Seno, volta para LOOP 1 SUM Coloca o resultado na sada Para. 3142 4542 Nmeros a serem somados 3325 1234 8786 0 0

0 SUM X P SUM

Figura 161: Cdigo fonte de um programa para uma CPU simples

Na Figura 161 ns vemos um exemplo de um programa escrito em assembler de uma CPU muito simples quando comparada com CPUs reais, mas muito complicada para os nossos propsitos, a CPU Pipoca, descrita em detalhes no Apndice A: A CPU Pipoca. Este programa soma os contedos das posies de memria com endereos entre 15 e 19 (usando os nomes os labels endereos entre X e XEND), e coloca o resultado na sada do processador. Vamos explicar somente alguns aspectos deste programa; no se preocupe em entende-lo em detalhe.

4 - Processadores

114

Instruction

Address10

Operand

1 1 1 1 LOOP 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

0 1 2 3 4

LOAD STORE LOAD STORE LOAD

Mode

Label

Comentrios

Size

0 0 0 0 1

5 ADD 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

Instrues
STORE LOAD ADD STORE COMPARE JMPLT JMP OUTPUT HALT

FINISH X

XEND SUM P

Dados

Zera o acumulador Coloca 0 em SUM Carrega o endereo X no acumulador Coloca o endereo X em P Carrega o contedo de SUM no acumulador Soma o contedo da posio de memria cujo 2 P endereo P ao acumulador 0 SUM Coloca o resultado na posio SUM 1 P Carrega o contedo de P 0 1 Soma 1 0 P Coloca o resultado em P 0 XEND Compara XEND com o acumulador 0 FINISH Se for menor, desvia para FINISH 0 LOOP Seno, volta para LOOP 1 SUM Coloca o resultado na sada Para. 3142 4542 Nmeros a serem somados 3325 1234 8786 0 0

0 SUM X P SUM

Figura 162: Um programa descreve a ocupao da nica memria por instrues e por dados

A primeira coisa a ser percebida que o programa descreve tanto instrues como dados, como mostra a Figura 162. A cada linha do programa corresponde uma palavra na memria. No campo de instruo, o programador coloca o mnemnico, e no o cdigo binrio de cada instruo. A coluna Label usada pelo programador para dar nomes a endereos de memria; estes labels podem ser usados na coluna Operando do programa fonte, tornando muito mais fcil modificar um programa quando se quer alterar a ocupao da memria. Na Figura 163 e na Figura 164 voc pode ver em destaque dois exemplos do uso de labels no programa fonte.

Carrega o endereo X no acumulador Coloca o endereo X em P Carrega o contedo de SUM no acumulador 4 - Processadores Soma o contedo da posio de memria cujo 1 5 05 ADD 2 P endereo P ao acumulador 1 6 06 STORE 0 SUM Coloca o resultado na posio SUM 1 7 07 LOAD 1 P Carrega o contedo de P Comentrios 1 8 08 ADD 0 1 Soma 1 1 9 09 STORE 0 P Coloca o resultado em P 1 10 0A COMPARE 0 XEND Compara XEND com o acumulador 1 0 00 LOAD 0 0 Zera o acumulador 1 11 0B JMPLT 0 FINISH Se for menor, desvia para FINISH 1 1 01 STORE 0 SUM Coloca 0 em SUM 1 12 0C JMP 0 LOOP Seno, volta para LOOP 2 02 LOAD X Carrega o endereo X no acumulador FINISH 1 13 OUTPUT 1 P SUM Coloca o endereo resultado X na sada 3 0D 03 STORE 0 em P 0E LOAD HALT Para. o contedo de SUM no acumulador LOOP 1 14 4 04 1 SUM Carrega X 1 15 0F 3142 Soma o contedo da posio de memria cujo 1 5 05 2 P 1 16 10 ADD 4542 endereo P ao acumulador Nmeros aposio serem somados 1 17 11 3325 Coloca o resultado 6 06 STORE 0 SUM na SUM 1 18 12 1234 7 07 LOAD 1 P Carrega o contedo de P XEND 1 19 13 ADD 8786 Soma 1 8 08 0 1 SUM 1 20 14 STORE 0 9 09 0 P Coloca o resultado em P P 1 10 21 0A 15 COMPARE 0 XEND 0 Compara XEND com o acumulador 1 Figura 11 0B JMPLT 0 FINISH Se for menor, desvia no para FINISH 163: Um exemplo de uso de labels como operandos cdigo fonte 1 12 0C JMP 0 LOOP Seno, volta para LOOP FINISH 1 13 0D OUTPUT 1 SUM Coloca o resultado na sada 1 14 0E HALT Para. X 1 15 0F 3142 Comentrios 1 16 10 4542 Nmeros a serem somados 1 17 11 3325 1 18 12 1234 LOOP 1 4 04 LOAD 1 SUM Carrega o contedo de SUM no acumulador XEND 1 19 13 8786 Soma o contedo da posio de memria SUM 1 1 20 5 14 05 ADD 2 0 P cujo endereo P ao acumulador P 1 21 15 0
Instruction Address10 Address16

1 1 LOOP 1

2 3 4

02 LOAD 03 STORE 04 LOAD

0 X 0 P 1 SUM

115

Instruction

Address10

Address16

1 1 1 1 1 1 1 FINISH 1

6 7 8 9 10 11 12 13

06 07 08 09 0A 0B 0C 0D

STORE LOAD ADD STORE COMPARE JMPLT JMP OUTPUT

0 1 0 0 0 0 0 1

SUM P 1 P XEND FINISH LOOP SUM

Operand

Mode

Label

Size

Operand

Mode

Label

Size

Coloca o resultado na posio SUM Carrega o contedo de P Soma 1 Coloca o resultado em P Compara XEND com o acumulador Se for menor, desvia para FINISH Seno, volta para LOOP Coloca o resultado na sada

Figura 164: Outro exemplo de uso de labels como operandos

Cada instruo no programa fonte deve ser codificada em bits para se ter uma imagem da memria gravada em alguma mdia, que ser carregada na memria do processador para a execuo do programa. Na Figura 165 voc pode ver um exemplo deste procedimento de codificao em bits, que chamado de montagem da instruo.

OpCode Mode Operand Instruo LOAD 1 SUM Cdigos 1000 01 0000010100 Binrio 1000 0100 0001 0100 Hexa 8414
Vem da tabela de cdigos de instruo SUM o nome dado posio x14 da memria

Figura 165: Montagem de uma instruo

4 - Processadores

116

A montagem de um programa, ou seja, a traduo do programa fonte para binrio, uma tarefa insana, com fortes exigncias de verificao. Mas essa tarefa s foi feita manualmente pelos pioneiros da computao. Cedo se percebeu que os computadores poderiam ser usados no somente para os clculos de bombas atmicas, que constituam sua finalidade primria, mas para automatizar o processo de montagem. Montadores, ou assemblers, so programas que lm programas, escritos por um programador, e geram arquivos com imagens binrias a serem carregadas na memria. Eles se encarregam da tarefa de substituir mnemnicos e labels pelos bits correspondentes, eliminando erros, e consequentemente a necessidade de verificao da montagem. Para programar a CPU Pipoca ns desenvolvemos uma planilha que se encarrega do processo de montagem de arquivos com imagens da memria. O Apndice A: A CPU Pipoca descreve com mais detalhes o circuito completo deste processador, assim como uma planilha que pode ser usada para a sua programao, ou para modificar seu micro-programa, modificando ou acrescentando novas instrues.

Programas Scilab

118

5 Programas Scilab
It is felt that FORTRAN offers as convenient a language for stating problems for machine solution as is now known. J.W. Backus, H. Herrick e I.Ziller40

5.1 Compiladores, Interpretadores e Sistemas Operacionais


Ns vimos como programar um processador usando micro-instrues, o que uma tarefa rdua mesmo para transformaes de informao extremamente simples como somar dois nmeros. Vimos tambm, sem entrar em maiores detalhes, que podemos programar um computador usando instrues, o que efetivamente representa um progresso com relao programao direta por sinais de controle codificados em micro-instrues. Mas isto no nem de longe uma tarefa confortvel para quem tem um problema de tranformao de informao mais ambicioso. Ao construir um programa usando instrues, o programador deve pensar em composies de instrues que refletem a arquitetura da mquina especfica em que est trabalhando: seus registradores, memrias, rotas de dados. A tarefa de programar se torna extremamente detalhada e propensa a erros. Alm disso, um programa feito para um computador no pode ser executado por um outro com um repertrio distinto de instrues. O processo de montagem manual dos bits das instrues de um programa escrito com mnemnicos pode ser feito com a ajuda de um assembler, um programa que l outro programa escrito com mnemnicos e labels, e faz automaticamente a montagem das instrues. Programas montadores melhoraram muito a vida dos programadores, que antes tinham que refazer todo o processo de montagem ao ter, por exemplo, uma posio de memria modificada. A montagem manual de instrues foi feita pelos primeiros programadores, ainda na dcada de 40. Montadores foram introduzidos no incio dos anos 50. Produzir programas que facilitam a programao na verdade uma idia central na cincia e na indstria da computao. Em 1954 a linguagem Fortran de Formula Translating foi proposta por um grupo de pesquisadores da IBM. com alguma emoo que ns, cientistas da computao, vemos o fac-smile do original datilografado, naturalmente do relatrio tcnico Preliminary Report: Specifications for the IBM Mathematical FORmula TRANslating System, FORTRAN41, mostrado na Figura 166. Fortran sem qualquer dvida a me de todas as linguagens. Tendo passado por diversas atualizaes, Fortran ainda uma linguagem muito utilizada por cientistas e engenheiros, e isso no deve mudar em um futuro breve. Um compilador um programa que tem como entrada um outro programa, escrito em uma linguagem de alto nvel, e que normalmente produz um programa equivalente ao que recebeu como entrada, escrito em linguagem de mquina para uma arquitetura especfica. O primeiro compilador Fortran foi escrito em assembler do IBM 704, uma mquina que tipicamente contava com 15K de memria. Desta poca at hoje j foram desenvolvidas com maior ou

40

John W. Backus et al, Preliminary Report: Specifications for the IBM Mathem atical FORmula TRANSlating System, FORTRAN | Computer History Museum, 1954, http://www.computerhistory.org/collections/accession/102679231. 41 Ibidem.

Programas Scilab

119

menor grau de sucesso muitas linguagens milhares delas, literalmente. Um mapa cronolgico com as principais linguagens de programao pode ser encontrado na referncia42.

Figura 166: Fac-smile do relatrio de especificao da linguagem FORTRAN 43

Outras linguagens importantes que so sucessoras diretas de Fortran so: Cobol, usada em aplicaes comerciais desde 1959, a linguagem C, de 1971, que pode produzir programas extremamente eficientes, C++, sucednea de C e que orientada a objetos, isto , permite a definio de dados e de operaes sobre estes dados de forma muito elegante, Basic, criada em 1964 e que bastante tempo depois recebeu grandes investimentos da Microsoft, Pascal, de 1970, muito usada como primeira linguagem em cursos de programao, Python, de 1991 que usada na plataforma de programao Google, Java, de 1995, que certamente a linguagem que hoje em dia recebe maiores investimentos da indstria de software, e PHP, de 1995, que tem muitos adeptos na comunidade de software livre (o Moodle escrito em PHP).

42

The History of Programming Languages - OReilly Media, acessado 7 de maro de 2011, http://oreilly.com/news/languageposter_0504.html. 43 Ibidem.

Programas Scilab

120

Existem ainda linguagens que seguem outros paradigmas de programao, como linguagens funcionais, das quais LISP provavelmente a mais importante, e linguagens lgicas como Prolog.

Figura 167: Compiladores, interpretadores e sistema operacional

A execuo de programa feito em uma linguagem de alto nvel depende de um processo de compilao ou interpretao. A Figura 167 mostra um arranjo tpico de componentes de software em um sistema computacional moderno: O programador produz um arquivo texto com o programa escrito em uma linguagem de alto nvel; esta forma do programa conhecida como programa fonte; Dependendo do seu ambiente de desenvolvimento e de execuo, o programa fonte pode ser compilado, isto , utilizado como entrada para um compilador, que produz um cdigo executvel (tambm chamado de programa objeto), armazenado como um outro arquivo, ou pode ser interpretado, isto , utilizado como entrada para um interpretador que se encarrega de produzir diretamente o efeito do programa. Programas em linguagem de alto nvel so compostos por comandos. Compiladores examinam o programa fonte completo antes de produzir o programa objeto, enquanto interpretadores podem examinar e executar comando por comando do programa fonte. Compiladores e interpretadores so programas como quaisquer outros, sendo resultado da compilao de programas fonte. Um programa objeto composto por instrues executveis pelo processador alvo; para cada arquitetura de processador necessrio adaptar o compilador ou construir um novo. Com isso um mesmo programa fonte pode ser utilizado em computadores com diferentes arquiteturas, desde que existam compiladores de sua linguagem para estas arquiteturas. Programas efetivamente especiais so os sistemas operacionais, como Windows, Linux ou MacOS. Sistemas operacionais coordenam o uso do processador, cujo tempo dividido entre a execuo de cdigos objeto de diversos programas e tambm do prprio sistema operacional. Programas objeto normais no tm instrues para acesso direto a equipamentos de entrada e sada, como discos ou o monitor. Operaes de entrada e sada so

Programas Scilab

121

realizadas exclusivamente pelo sistema operacional, que oferece estas operaes como servios utilizados pelos programas comuns. Com isso, o sistema operacional consegue administrar conflitos no uso dos dispositivos de E/S, e tambm permitir que programas normais possam desfrutar de abstraes confortveis como arquivos e diretrios, ao invs de terem que lidar com detalhes de cada unidade de disco. Isso faz com que compiladores tenham tambm que ter adaptaes para cada sistema operacional. Por exemplo, um compilador C deve ter uma verso para Windows e outra para Linux. Uma mesma linguagem pode ser implantada por compilao ou por interpretao. Mesmo se tradicionalmente C e Fortran so linguagens implantadas por compilao, nada impede que interpretadores sejam construdos para estas linguagens, e que compiladores sejam construdos para linguagens tradicionalmente interpretadas como Scilab e Matlab, das quais falaremos a seguir.

5.2 Scilab
Nos fins dos anos 70 Cleve Moler criou uma linguagem, Matlab44, voltada para o tratamento de matrizes, que, em 1984, foi lanada comercialmente pela empresa MathWorks. Matlab vem de Matrix Laboratory, e um fenmeno de sucesso entre engenheiros e cientistas. O Matlab um interpretador. Scilab, a linguagem que adotamos neste curso, desenvolvida desde 1990 por pesquisadores do Institut Nacional de Recherche en Informatique et Automatique, o INRIA, e da cole Nationale des Ponts et Chausses, duas instituies francesas. muito semelhante ao Matlab e, fator importante para sua escolha, gratuito. O Scilab tambm um ambiente de desenvolvimento e interpretao de programas; a verso utilizada neste texto a 5.4.0. Do ponto de vista da cincia da computao, Matlab e Scilab no mereceriam destaque em uma galeria de linguagens de programao. Entretanto, a facilidade que oferecem para a construo de pequenos programas voltados para engenharia e cincia no encontra rival nas linguagens tradicionais como Fortran, C ou Java. Antes de entrarmos na apresentao do ambiente e da linguagem Scilab queremos colocar algumas observaes gerais sobre linguagens de programao, que voc deve ter em mente ao iniciar seu estudo. Linguagens de programao so linguagens formais, assim chamadas por contraste com linguagens naturais como portugus ou ingls. Uma linguagem de programao, como as linguagens naturais, une riqueza de expresso a detalhes sintticos e algumas arbitrariedades. Detalhes e arbitrariedades frequentemente vm de escolhas feitas no passado, incluindo algumas que j no fazem mais sentido mas que so mantidas por uma inrcia natural. Seu aprendizado exige uma postura paciente, pois envolve no incio uma taxa relativamente alta de memorizao. Como acontece com as linguagens naturais, a fluncia vem com o uso, e com a fluncia vem a percepo da riqueza da linguagem. Como dissemos, Scilab tambm um ambiente que interpreta comandos e programas. Ele oferece uma console para interao com o usurio, um editor para a construo de programas, o SciNotes, e tambm emite mensagens de erros relativos tanto obedincia de comandos e programas s regras da linguagem como a problemas que podem ocorrer na execuo, como uma diviso por zero.

44

Mathworks, MathWorks - MATLAB and Simulink for Technical Computing.

Programas Scilab

122

Prompt de Comandos

Figura 168: cone e tela inicial com a console do Scilab

A Figura 168 mostra a tela obtida ao clicar sobre o cone do Scilab. uma tela com quatro painis, uma barra de menus e uma barra de ferramentas. A janela central, , sobre a qual iremos inicialmente concentrar nossa ateno, a console, com um prompt de comandos, indicado pela setinha --> . nesse prompt que so digitados comandos a serem interpretados pelo Scilab.

5.3 Variveis e Comandos de Atribuio

a uma varivel
que passa a existir, recebe e guarda um valor O Scilab ecoa o valor recebido pela varivel

Variveis criadas

Histrico

Figura 169: Um comando de atribuio

O principal comando que transforma informao chamado comando de atribuio. Um primeiro exemplo est na Figura 169, que mostra o efeito no Scilab da digitao na console do comando a = 2 + 2, seguida de <enter>. Aqui, a uma varivel que passa a existir no

Programas Scilab

123

interpretador, e que recebe e armazena um valor - no caso, 4. A existncia dessa varivel confirmada pelo painel de navegao de variveis, no canto superior direito da tela. Aps executar um comando de atribuio o Scilab ecoa o seu valor, isto , imprime na console o valor recebido pela varivel. Variveis so nomes para espaos de memria gerenciados pelo Scilab; um programador no precisa ter qualquer idia de como esse gerenciamento feito. Variveis tm seus nomes escolhidos pelo programador segundo algumas regras: O primeiro caractere do nome deve ser uma letra, ou qualquer caractere dentre '%', '_', '#', '!', '$ e ?'; Os outros podem ser letras ou dgitos, ou qualquer caractere dentre '_', '#', '!', '$ e '?' . Mesmo sendo um produto francs, o Scilab no permite o uso de letras acentuadas ou de cedilhas em nomes de variveis.

Exemplos de nomes de variveis vlidos so a, A, jose, total_de_alunos, #funcionarios. O Scilab distingue entre maisculas e minsculas e, portanto, a e A seriam variveis diferentes. Nomes no vlidos so 1Aluno (porque o primeiro caractere um algarismo), total de alunos (porque tem espaos), ou jos (porque acentuado).

^ denota exponenciao

* denota multiplicao

O valor atribudo pode ser uma expresso aritmtica com variveis j conhecidas
Figura 170: Variveis e comandos de atribuio

Aps a execuo dos comandos na Figura 170, o painel de navegao de variveis teria o formato mostrado na Figura 171, com as variveis a, b e c criadas.

Figura 171: Navegador de variveis aps a execuo dos comandos na Figura 170

Programas Scilab Um comando de atribuio tem o formato <varivel alvo> = <expresso> onde:

124

A <varivel alvo>, se no existia, passa a existir; Se existia, o valor anterior perdido; Na execuo do comando, a <expresso> calculada, e o resultado atribudo <varivel alvo>.

-->d = a+x !--error 4 Undefined variable: x -->b = 2*b = 2048.

A expresso pode conter b a varivel alvo, em uma estrutura similar a um registrador acumulador

Todas as variveis em uma expresso devem estar definidas, ou o Scilab reclama

Figura 172: Usos e erros em comandos de atribuio

Conforme ilustrado na Figura 172, todas as variveis envolvidas na <expresso> devem ter valores definidos no momento da execuo do comando. Vale ainda observar que a <expresso> pode conter a <varivel alvo>, em um arranjo similar ao utilizado nos registradores acumuladores.

-->a = %pi a = 3.1415927 -->b = 2*%pi;

Valor prdefinido ; suprime o eco automtico

-->c = cos(a) + sqrt(b) c = O Scilab oferece um sem1.5066283


nmero de funes prdefinidas (sqrt = square root).
Figura 173: Exemplos de comandos de atribuio com variveis com valor pr-definido, supresso de eco e funes elementares

O Scilab oferece tambm variveis com valores pr-definidos, como %pi ou %e, e uma enorme variedade de funes pr-definidas (veja a Figura 174). Valores numricos so representados no Scilab em ponto flutuante de 64 bits; %pi forma que temos para, em um programa, nos referirmos melhor aproximao de nessa representao; o mesmo vale para %e e outras constantes. Um detalhe muito til a possibilidade de supresso do eco automtico, que algumas vezes polui a tela com informao desnecessria, e que obtido com o uso de um ; colocado aps o comando de atribuio.

Programas Scilab

125

Figura 174: Lista de funes elementares encontrada no help do Scilab

A construo e a compreenso de expresses aritmticas mais elaboradas exige o conhecimento das regras de prioridades entre operadores e o uso de parnteses para se obter o resultado desejado. Como um exemplo, qual valor ser atribudo a uma varivel x pelo comando x = 2^3*4, o valor 234 = 212 = 4096, ou o valor 23 4 = 8 4 = 32? A Figura 175 mostra as prioridades empregadas pelo Scilab no clculo de expresses. Ali vemos que a potenciao tem prioridade sobre a multiplicao, e portanto o valor atribudo a x pelo comando acima ser 23 4 = 8 4 = 32.

Prioridade 1a 2a

Operao Potenciao Multiplicao, diviso Adio, subtrao

3a

Figura 175: Prioridades de operadores aritmticos

Se a inteno do programador era atribuir a x o valor 234 = 212 = 2048, parnteses deveriam ter sido usados no comando de atribuio, como em x = 2^(3*4).

Programas Scilab

126

-->2^3*4 ans = 32. ->2^(3*4) ans = 4096. -->2^3^4 ans = 2.418D+24 ->2^(3^4) ans = 2.418D+24 ->(2^3)^4 ans = 4096. -->2*3+4 ans = 10. ->2*(3+4) ans = 14.

Figura 176: Prioridades e parnteses influenciando o valor de uma expresso aritmtica

Na Figura 176 ns vemos alguns exemplos de como o Scilab interpreta expresses aritmticas. De uma forma geral, recomendvel o uso de parnteses para tornar clara a ordem em que o programador deseja que as operaes de uma expresso sejam realizadas. Em Scilab (como em Fortran, C, Java, e praticamente todas as linguagens de programao) no se usam chaves ou colchetes; somente parnteses so usados, e a cada parnteses aberto deve corresponder um parnteses fechado. Toda expresso deve ser escrita de forma linear; por exemplo,

Programas Scilab

127

+ 2 4 2 em Scilab assume a forma (-b+sqrt(b^2 4*a*c))/(2*a), onde usamos cores para ressaltar a correspondncia entre parnteses abertos e fechados.

5.4 Usando o Scilab como Calculadora


Para mostrar a utilidade de um programa, vamos primeiramente resolver com a console Scilab uma equao de segundo grau, com a forma que conhecemos desde a escola secundria: 2 + + = 0 Ns queremos calcular as razes para = 534.2765, = 9987.3431 e = 225.7690. Ns sabemos que as razes so encontradas pelas frmulas 1 = e 2 = onde = 2 4 . Temos aqui um problema de transformao de informao: dos valores de , e , queremos obter valores para 1 e 2 . Em todo problema de transformao de informao, mesmo antes de tentar resolv-lo, temos que pensar em testes que verifiquem a correo do que consideramos ser uma soluo. No caso, dispomos de um teste simples: valores 1 e 2 que venham a ser encontrados devem ser tais que o valor calculado de () = 2 + + seja igual a zero nesses pontos. A primeira coisa que faremos inicializar variveis a, b e c, conforme mostrado na Figura 177. 2 + 2

Programas Scilab

128

-->a = 534.2765 a = 534.2765 -->b = 9987.3431 b = 9987.3431 -->c = 225.7690 c = 225.769


Figura 177: Inicializao dos coeficientes de uma equao de 2o grau

Depois, calculamos e as razes, como mostrado na Figura 178.

Programas Scilab

129

-->delta = b^2 - 4*a*c delta = 99264530. -->r1 = (b+sqrt(delta) )/(2*a) r1 = - 0.0226329 -->r2 = (-bsqrt(delta))/ (2*a) r2 = - 18.670578
Figura 178: Clculo das razes da equao de 2o grau

Repare que usamos variveis delta, r1 e r2, com nomes aceitveis para o Scilab e, principalmente, com significado para ns. Repare tambm nas expresses usadas nos comandos de atribuio. Erros comuns cometidos por iniciantes so: escrever delta = b^2 4ac, omitindo os operadores de multiplicao, que entretanto so imprescindveis para que o Scilab compreenda a expresso, ou escrever r1 = (-b+sqrt(delta))/2*a, o que na verdade levaria ao clculo de 1 = (
+ ) . , 2

o que no o que queremos.

O primeiro erro menos grave, pois o Scilab ir detetar que existe algo de errado com o comando, e ir manifestar seu estranhamento por uma mensagem como a da Figura 179. Este tipo de erro conhecido como erro de sintaxe. -->delta = b^2 - 4ac !--error 276 Operador, comma, ou semicolon faltante.

Programas Scilab
Figura 179: Mensagem de erro de sintaxe detetado pelo Scilab

130

O Scilab no consegue entretanto identificar erros do segundo tipo, conhecidos como erros de semntica. A sintaxe da expresso est perfeita, mas seu significado sua semntica no aquela que desejvamos. Por isso, sempre bom verificar os resultados de um clculo ou de um programa. Para a nossa equao de segundo grau podemos tambm usar o Scilab para a verificao, com os comandos mostrados na Figura 180. Nesta figura voc deve reparar: na apario da varivel ans, que utilizada pelo Scilab para armazenar resultados de expresses que no fazem parte de um comando de atribuio; na notao 3.865D-12, que a forma de se escrever o valor literal 3.865 1012 .

Ali vemos que o valor do polinmio da equao nas razes que calculamos no exatamente zero. Isso no deve constituir preocupao, pois os valores so relativamente muito pequenos, da ordem de 1012 para r1, e 1013 para r2. Nmeros no Scilab so armazenados como ponto flutuante de 64 bits (veja a Seo 2.1), onde as operaes podem envolver arredondamentos.

Programas Scilab

131

->a*r1^2 + b*r1 + c ans = 3.865D12 ->a*r2^2 + b*r2 + c ans = 2.274D13

Figura 180: Verificando os resultados

Programas Scilab

132

Muito bem, conseguimos usar o Scilab para resolver uma equao de 2 grau, o que no chega a ser uma faanha. Mas tivemos ganhos com relao execuo dos mesmos clculos com uma calculadora de mo: o uso de variveis evita re-digitaes e possveis erros; resultados intermedirios so memorizados e podem ser reaproveitados; o uso de frmulas como na Figura 178 aumenta muito a confiana nos clculos.

As limitaes do uso direto da console Scilab para clculos tornam-se claras quando queremos resolver outra equao de 2 grau. Frmulas tm que ser re-digitadas, abrindo ocasio para erros, com pouco aproveitamento do trabalho j feito. A soluo para isso usar o Scilab como um interpretador de programas.

5.5 Programas Scilab


Um programa fonte Scilab um arquivo texto cujo nome tem a terminao .sce. Um arquivo-programa contm comandos Scilab, e construdo usando o editor SciNotes (veja na Figura 181 como o editor aberto no Scilab 5.1). A execuo (interpretao) de um programa se faz seguindo o menu Executar da console do SciNotes; essa execuo equivale digitao na console dos comandos presentes no arquivo.

Editor de Programas

Figura 181: Abrindo o editor SciNotes

Ateno: nunca use o Word ou qualquer outro editor de textos sofisticado para abrir e/ou editar arquivos de programas. Esses editores podem introduzir bits de informao de formatao, o que perturba completamente a interpretao do programa pelo Scilab. No editor SciNotes voc pode: Criar um novo programa, atravs do menu Arquivo/Novo; Abrir para edio um programa j existente, atravs do menu Arquivo/Abrir Editar um programa Salvar o programa editado, atravs do menu Arquivo/Salvar Executar um programa, atravs do menu Executar

e vrias outras coisas que voc ir aprendendo aos poucos.

Programas Scilab

133

O Scilab trabalha com um diretrio corrente, que a primeira opo de localizao para procurar e para salvar arquivos. Na console do Scilab voc pode escolher o diretrio corrente atravs do menu Arquivo/Alterar o Diretrio Atual, ou clicando duas vezes sobre um diretrio no painel de navegao de arquivos, que sempre mostra o diretrio corrente no ponto mais alto da hierarquia exibida. O diretrio corrente do SciNotes o diretrio corrente do Scilab no momento em que o editor aberto. Um conselho: organize os seus arquivos! Perde-se muito tempo procurando arquivos gravados aonde mesmo?. O autor destas linhas cria um diretrio para cada mdulo do curso, onde so colocados todos os arquivos que ali so utilizados; voc pode adotar uma organizao similar em seu computador pessoal. Ao usar computadores compartilhados, crie um diretrio de trabalho com o seu nome, o que ir facilitar a sua limpeza posterior.

Figura 182: O SciNotes editando o programa Eq2g1.sce

A Figura 182 mostra um programa que tem em cada linha exatamente os mesmos comandos que utilizamos na console para resolver a equao de 2 grau. Ns demos a este programa o nome Eq2g1.sce; usamos um nmero no nome do arquivo porque faremos outras verses deste mesmo programa. As duas primeiras linhas do programa Eq2g1.sce se iniciam por //, o que faz com que sejam ignoradas pelo Scilab no momento da execuo. Essas linhas so comentrios, e tm o importantssimo objetivo de melhorar a compreenso de um programa por um leitor humano.

Programas Scilab

134

Figura 183: Executando um programa a partir do editor SciNotes

Para executar o programa, voc pode usar o menu Executar/...file with no echo ou Executar/...file with echo, conforme mostra a Figura 183. Experimente as duas possibilidades, e veja os resultados na console do Scilab. Com um programa gravado em um arquivo, se quisermos resolver uma nova equao, bastar substituir no programa os valores dos novos coeficientes e execut-lo novamente. Comparando com o processo de resoluo via console, o uso de um programa reduz consideravelmente o trabalho e as chances de erros de digitao. Entretanto, a prtica de se alterar programas para introduzir dados que se modificam a cada execuo no recomendvel, e nem exeqvel quando o volume de dados muito grande. O melhor a fazer modificar o programa para permitir que o usurio defina os valores dos coeficientes a cada execuo.

Programas Scilab

135

// Clculo das razes de uma equao // de 2o grau a = input("Digite o valor de a:") b = input("Digite o valor de b:") c = input("Digite o valor de c:") delta = b^2 4*a*c r1 = (b+sqrt(delta))/ (2*a) r2 = (-bsqrt(delta))/(2 *a)

Figura 184: O programa Eq2g2.sce com os comandos de dilogo em destaque

Programas Scilab O comando input permite essa interao com o usurio em tempo de execuo. Como vemos na Figura 184, este comando recebe como parmetro uma frase a ser exibida para o usurio, que normalmente usada para solicitar o valor a ser digitado.

136

Programas Scilab

137

Digite o valor de a:1 a = 1. Digite o valor de b:2 b = 2. Digite o valor de c:3 c = 3. delta = - 8. r1 = - 1. + 1.4142136i r2 = - 1. 1.4142136i

Figura 185: Execuo do programa Eq2g2.sce

A Figura 185 mostra a console do Scilab em uma execuo do programa Eq2g2.sce, onde voc pode verificar o efeito da execuo dos comandos input. Os valores digitados pelo usurio para os coeficientes a, b e c foram, respectivamente, 1, 2 e 3. Estes valores levam a um

Programas Scilab negativo, e o exemplo serve tambm para ilustrar a naturalidade com que o Scilab trata nmeros complexos.

138

5.6 Valores Lgicos e Strings


Uma varivel Scilab pode armazenar tambm valores lgicos correspondentes a verdadeiro e falso, denotados pelos literais Scilab %t e %f (true e false), ou %T e %F. A Figura 186 mostra um exemplo de atribuio de valores lgicos a variveis usando a console do Scilab.

-->p = p = T -->q = q = T -->r = r = T -->s = s = F -->t = t = T

%t

Literal True Expresso Relacional OR

5 > 2

p | q

p & q

AND
~ s

NOT

Figura 186: Atribuico de valores lgicos a variveis na console do Scilab

Variveis com valores lgicos podem ser parte de expresses lgicas, que usam os operadores lgicos ~ (NOT), & (AND) e | (OR), definidos, como voc pode esperar, exatamente como na Figura 57 (pgina 48).

> >= < <= == <> ou ~=

maior que maior ou igual a menor que menor ou igual a igual a diferente de

Figura 187: Operadores relacionais

Expresses lgicas frequentemente fazem uso de comparaes entre valores de expresses aritmticas para obter um valor lgico. A Figura 187 mostra os operadores relacionais usados no Scilab, onde voc pode reparar que igual a representado por dois = adjacentes, uma herana da linguagem C, e que existem duas formas de representao de diferente de.

Programas Scilab -->a = 5 > 7 a = F -->b = (2+1) == 3 b = T -->c = (4-3) <= 0 c = F


Figura 188: Exemplos de expresses lgicas utilizando operadores relacionais

139

Alm de valores lgicos, variveis Scilab podem armazenar outros dados no numricos. Na Figura 189 ns vemos exemplos de como atribuir sequncias de caracteres o termo usado em ingls, strings a variveis.

-->a = "Programao" a = Programao Aspas simples (') e duplas -->b = " de ' (") so equivalentes b = de -->c = "Computadores" c = Computadores
Figura 189: Atribuindo strings a variveis

Strings so escritos entre aspas, simples ou duplas. Voc pode mesmo iniciar um string com aspas duplas e termin-lo com aspas simples.
Para strings, + significa concatenao

-->a = 'Programao'; -->b = ' de '; -->c = 'Computadores'; -->Disciplina = a + b + c Disciplina = Programao de Computadores
Figura 190: Concatenao de strings

Uma operao comum com strings a concatenao, que consiste na justaposio de dois strings. No Scilab a concatenao utiliza o mesmo smbolo da adio numrica, o +.

Fim do string?
-->x = 'String "com aspas"' !--error 276 Missing operator, comma, or semicolon

Figura 191: Erro ao tentar representar um string contendo aspas

Programas Scilab

140

Aspas so usadas para marcar o incio e o fim de strings, e isto pode provocar um pequeno problema ao se tentar representar strings que contm aspas, como mostrado na Figura 191. Para conseguir isso, basta colocar duas aspas consecutivas na posio desejada, como na Figura 192. -->x = 'String ""com aspas duplas""' x = String "com aspas duplas" -->x = 'String ''com aspas simples''' x = String 'com aspas simples'
Figura 192: Strings contendo aspas

Strings formados por algarismos no so nmeros para o Scilab. O string '3.1415926' na verdade armazenado como uma sequncia dos caracteres ASCII ou UTF-8 3, ., 1, 4, etc., e no como um nmero de ponto flutuante, como mostrado na Figura 55. Se tentarmos realizar operaes aritmticas com strings de algarismos, o Scilab ir emitir uma mensagem de erro apropriada: -->2*'3.1415926' !error 144 Undefiled operation for the given operands
Figura 193: Strings formados por algarismos no so nmeros para o Scilab

Se uma varivel s contm um string em um formato numrico ( o que inclui strings como 2.3D-23), o comando x = eval(s) coloca em x o valor de s convertido para um nmero codificado em ponto flutuante. A funo isnum(s) pode ser usada para verificar se s contm um string vlido para a converso Se x contm um valor em ponto flutuante, a funo string(x) pode ser usada para obter sua converso para um string com algarismos, sinais e expoentes de um nmero decimal com valor aproximadamente igual ao valor de c. O comando printf, que veremos a seguir, permite converter um valor em ponto flutuante com um maior controle sobre seu formato. Strings tambm podem ser lidos pelo comando input, como no exemplo Nome = input("Seu nome, por favor"). Escrevendo dessa forma o comando input o usurio deve digitar o seu nome entre aspas. possvel eliminar a necessidade de escrita do string entre aspas usando o comando input com um parmetro extra, um string com o valor "string", como no comando input("Seu nome, por favor","string"). -->Nome = Seu nome: Undefined Seu nome: Nome = Jose input("Seu nome: ") Jose variable: Jose "Jose"

-->Nome = input("Seu nome: ","string") Seu nome: Jose Nome = Jose


Figura 194: Exemplos de uso do comando input na console do Scilab

Programas Scilab

141

5.7 Os comandos if-then-else e printf


Para enriquecer nosso repertrio de comandos Scilab, vamos agora construir um terceiro programa que resolve equaes do 2 grau, mas com as seguintes alteraes na especificao: o programa s dever calcular as razes quando elas forem reais; a sada do programa dever ser uma frase como As razes so xxxx e xxxx, quando as razes forem reais e, seno, As razes so complexas. a = input("Valor de a: "); b = input("Valor de b: "); c = input("Valor de c: "); delta = b^2 - 4*a*c; if delta >= 0 then r1 = (-b+sqrt(delta))/(2*a); r2 = (-b-sqrt(delta))/(2*a); printf("As razes so %6.3f e %6.3f",r1,r2); else printf("Razes complexas"); end
Figura 195: O programa Eq2g3.sce

A Figura 195 mostra o programa Eq2g3.sce, que atende a essas especificaes. Repare que estamos usando ; aps vrios dos comandos de atribuio, o que suprime o eco do Scilab e torna a sada mais limpa. if <condio> then <bloco ento> else <bloco seno> end
Figura 196: O comando if

Este programa introduz dois novos comandos: if e printf. O comando if usado para prescrever comportamentos condicionais na execuo do programa. Sua forma geral est mostrada na Figura 196, onde: if, then, else e end so as palavras-chave que o Scilab usa para reconhecer o comando; if marca o incio do comando; <condio> uma expresso lgica, tipicamente uma comparao entre expresses aritmticas, cujo valor avaliado como verdadeiro ou falso; then separa a <condio> do <bloco ento>; <bloco ento> e <bloco seno> so conjuntos arbitrrios de comandos Scilab; else marca o fim do <bloco ento> e o incio do <bloco seno>; end a palavra-chave que fecha o comando if. na execuo do comando if, o <bloco ento> executado se e somente se a <condio> for verdadeira, e o <bloco seno> executado se e somente se a <condio> for falsa.

Programas Scilab

142

Em alguns casos no desejamos executar nenhum comando no caso da <condio> ser falsa, e o comando pode assumir uma forma simplificada, sem a clusula else, como mostrado na Figura 197. if <condio> then <bloco ento> else // Nenhum comando aqui End

if <condio> then <bloco ento> End

Figura 197: Duas formas equivalentes do comando if, a da direita sem a clusula else

A Figura 198 mostra os blocos de comandos e a condio do comando if do programa Eq2g3.sce.

<condio>

<bloco ento>

if delta >= 0 then r1 = (-b+sqrt(delta))/(2*a) r2 = (-b-sqrt(delta))/(2*a) printf("As razes so %g e %g",r1,r2) else printf("As razes so complexas") end <bloco seno>
Figura 198 :Partes do comando if do programa Eq2g3.sce

O comando printf tem a forma printf(<frase>,<lista de expresses>) onde <frase> a sentena que se quer imprimir na tela, e um string que pode estar entremeado por cdigos de formato como %g; %g um cdigo de formato geral para expresses com valores numricos (ns veremos em seguida expresses com outros tipos de valores); existem vrios outros cdigos de formato como %d, %f , %e ou %s, que iremos explorar em exerccios e em outros exemplos neste texto. <lista de expresses> uma lista de expresses separadas por vrgulas, que so calculadas no momento da execuo do comando; os valores resultantes das expresses na lista so mapeadas um a um nos cdigos de formato, na mesma sequncia em que aparecem na <frase>, e a sentena impressa obtida pela substituio do valor da expresso na posio marcada pelo cdigo de formato.

No comando printf("As razes so %g e %g",r1,r2)as duas expresses na lista so muito simples, formadas por uma varivel. A expresso r1 mapeada no primeiro %g, e a expresso r2 mapeada no segundo %g. A Figura 199 mostra uma sada do programa Eq2g3.sce onde se pode ver o efeito da execuo deste comando.

Programas Scilab Digite o valor de a:3 Digite o valor de b:4 Digite o valor de c:1 delta = 4. r1 = - 0.3333333 r2 = - 1. As razes so -0.333333 e -1
Figura 199: Uma sada do programa Eq2g3.sce

143

Vamos agora exercitar nossas novas habilidades fazendo um programa que: Leia o nome do aluno, que responde, por exemplo, Jos; Leia tambm o total de pontos obtidos pelo aluno; Imprima, conforme o caso, a frase <aluno>, com <pontos> voc passou!, ou ento, caso o aluno no tenha obtido um mnimo de 60 pontos, a frase <aluno>, com <pontos> voc no passou! Exemplos seriam Jos, com 80 pontos voc passou!, ou Jos, com 40 pontos voc no passou!

// Leitura do nome do aluno Nome = input("Seu nome, por favor:"); // Leitura dos pontos obtidos Pontos = input(Nome + ", quantos pontos voc conseguiu?"); // Deciso e impresso do resultado if Pontos >= 60 then printf("%s, com %g pontos voc passou!",Nome,Pontos); else printf("%s, com %g pontos voc no passou!",Nome,Pontos); end
Figura 200: O programa PassouNaoPassou.sce

A Figura 200 mostra o programa PassouNaoPassou.sce que atende a esta especificao. Seu nome, por favor:"Maria" Maria, quantos pontos voc conseguiu?90 Maria, com 90 pontos voc passou! Seu nome, por favor:"Jose" Jose, quantos pontos voc conseguiu?47 Jose, com 47 pontos voc no passou!
Figura 201: Duas execues do programa PassouNaoPassou.sce

Dois exemplos de execues deste programa esto na Figura 201. Neste programa importante observar: A frase utilizada no comando input para a varivel Pontos o resultado de uma operao de concatenao (+); Os comandos printf utilizam o cdigo de converso %s, apropriado para strings.

Estes dois truques so exemplos de manipulao de strings que podem tornar mais simptica a interao de um programa com seu usurio.

Programas Scilab

144

6 - Matrizes

145

6 Matrizes
Matrizes no Scilab so variveis que contm um nmero potencialmente grande de valores. na manipulao de matrizes que o Scilab (seguindo o Matlab) mostra uma grande superioridade sobre linguagens como C ou Fortran.

6.1 Matrizes e Comandos de Atribuio

-->A = [1 2 3; 4 5 6] A = 1. 4. 2. 5. 3. 6.

Figura 202: Atribuindo valores literais a uma matriz

A Figura 202 mostra uma maneira simples de se criar uma matriz atravs de um comando de atribuio na console do Scilab. Os valores dos elementos da matriz so dispostos entre colchetes. Espaos (poderiam ser vrgulas) separam elementos, e ; separa linhas. possvel extrair o valor de um elemento especfico da matriz, designado por seus ndices entre parnteses, como mostrado na Figura 203, e tambm podemos atribuir um valor a um elemento especfico de uma matriz, como mostrado na Figura 204.

-->A = [1 2 3; 4 5 6] A =
1. 4. 2. 5. 3. 6.

-->e = A(2,3) e = 6.
Figura 203: Obtendo o valor de um elemento de uma matriz

A(2,3) , por exemplo, refere-se ao elemento na segunda linha e na terceira coluna; A(1,2) o elemento na primeira linha e na segunda coluna.

-->A(1,2) = 33

= 1. 4.

33. 5.

3. 6.

Figura 204: Atribuindo um valor a um elemento de uma matriz

6 - Matrizes

146

O Scilab to orientado para matrizes que todas as variveis Scilab so matrizes. As variveis simples com que temos trabalhado so, na verdade, matrizes com uma nica linha e uma nica coluna. possvel perceber isso usando o comando [nl,nc] = size(A) para obter as dimenses de uma matriz A . A funo size retorna dois parmetros, o nmero de linhas e o nmero de colunas da matriz. A Figura 205 mostra dois exemplos de uso da funo size. -->A = [1 2 3; 4 5 6]; -->[nl,nc] = size(A) nc = 3. nl = 2. -->k = 0; -->[L,C] = size(k) C = 1. L = 1.
Figura 205: Matrizes e a funo size

Uma matriz cresce quando atribumos valores a elementos com ndices superiores aos ndices j referenciados. Por exemplo, quando fazemos x = 7 estamos criando uma matriz 1 x 1; se em seguida fizermos x(2,3) = 13, a matriz x assume as dimenses 2 x 3, e os elementos no referenciados recebem o valor zero, como mostrado na Figura 206.

-->x = 7; -->x(2,3) x = 7. 0.

// matriz 1x1 = 13 0. 0. 0. 13.

Figura 206: Expanso de uma matriz

Vetores so matrizes de uma nica linha ou de uma nica coluna. A Figura 207 mostra a criao na console do Scilab de um vetor linha e de um vetor coluna. Para referenciar o elemento X(i,1) de um vetor coluna ou para referenciar o elemento X(1,i) de um vetor linha o Scilab permite a utilizao da notao X(i), deixando o ndice 1 implcito em ambos os casos.

-->v = [10 20 30] v = 10. 20. 30. -->u = [10; 20; 30] u = 10. Lembrando que o 20. ; separa linhas 30.
Figura 207: Um vetor linha e um vetor coluna

6 - Matrizes O Scilab permite que uma parte de uma matriz seja referenciada tanto para a atribuio de valores como para a recuperao de valores armazenados.
x = 23. 23. 21. 88. 65. 30. 93. 21. 31. 36. 29. 56. 48. 33. 59. 50. 43. 26. 63. 40. 91. 4. 48. 26. 41. 28. 12. 77. 21. 11. 68. 15. 69. 84. 40.

147

-->x(2:4,3:5) = -1 x =

23. 23. 21. 88. 65.

30. 93. 21. 31. 36.

29. - 1. - 1. - 1. 59.

50. - 1. - 1. - 1. 40.

91. - 1. - 1. - 1. 41.

28. 12. 77. 21. 11.

68. 15. 69. 84. 40.

Figura 208: Atribuindo um valor a uma parte de uma matriz

Se x contm uma matriz 7x5, x(2:4,3:5) denota a parte da matriz compreendida pela interseo das linhas de 2 a 4 e das colunas de 3 a 5, como mostrado na Figura 208.
x = 40. 87. 11. 19. 56. 58. 68. 89. 50. 34. 38. 92. 94. 34. 37. 73. 26. 49. 26. 52. 53. 11. 22. 62. 76. 4. 67. 20. 39. 83. 58. 48. 22. 84. 12.

-->x(3:4,4:5) = [-1 -2;-3 -4] x = 40. 58. 38. 73. 53. 87. 68. 92. 26. 11. 11. 89. 94. - 1. - 2. 19. 50. 34. - 3. - 4. 56. 34. 37. 52. 76.

4. 67. 20. 39. 83.

58. 48. 22. 84. 12.

Figura 209: Atribuindo os valores de uma matriz a uma parte de outra matriz

A Figura 209 mostra outro exemplo de utilizao desta notao.


x = 21. 75. 0. 33. 66. 62. 84. 68. 87. 6. 56. 66. 72. 19. 54. 23. 23. 21. 88. 65. 30. 93. 21. 31. 36. 29. 56. 48. 33. 59. 50. 43. 26. 63. 40.

-->a = x(2,:) a = 75. 84. 66. 23. 93. 56. 43.

Figura 210: Obtendo todos os valores de uma linha de uma matriz

Ao se referenciar a uma parte de uma matriz que contm, seja todas as linhas, seja todas as colunas da matriz, possvel usar uma notao simplificada com :. A Figura 210 mostra um exemplo de uso desta notao para obter todos os elementos em uma linha de uma matriz.

6 - Matrizes
x = 91. 4. 48. 26. 41.

148

28. 12. 77. 21. 11.

68. 15. 69. 84. 40.

40. 87. 11. 19. 56.

58. 68. 89. 50. 34.

38. 92. 94. 34. 37.

73. 26. 49. 26. 52.

-->b = x(:,3:5) b = 68. 40. 58. 15. 87. 68. 69. 11. 89. 84. 19. 50. 40. 56. 34.
Figura 211: Obtendo os elementos de todas as linhas nas colunas de 3 a 5

Outro exemplo est mostrado na Figura 211, onde x(:,3:5) designa a parte de x formada pelos elementos em todas as linhas e nas colunas de 3 a 5.

6.2 Aritmtica matricial


No Scilab as variveis numricas so sempre matrizes e, em conseqncia, as operaes aritmticas usuais (+, -, *, /, ^) so entendidas pelo Scilab como operaes matriciais da lgebra linear. Desta forma, a*b designa o produto matricial de uma matriz a por uma matriz b. Quando o que se deseja uma operao elemento a elemento, os mesmos smbolos devem ser utilizados precedidos por um ., como .* ou .^. -->x = [1 2 3; 4 5 6]; -->y = [10 20 30; 40 50 60]; -->x + y ans = 11. 22. 33. 44. 55. 66. -->x - y ans = - 9. - 18. - 27. - 36. - 45. - 54.
Figura 212: Adio e subtrao de matrizes

A Figura 212 mostra exemplos de adio e subtrao de matrizes. Como estas operaes so sempre feitas elemento a elemento, os operadores .+ e .- no so necessrios, e no existem no Scilab.

6 - Matrizes
-->x = [1 2 3; 4 5 6] x = 1. 2. 3. 4. 5. 6. -->y = [10 20; 30 40; 50 60] y = 10. 20. 30. 40. 220 = 1x10 + 2x30 + 3x50 50. 60. -->x * y ans = 220. 280. 490. 640.
Figura 213: Exemplo de produto matricial

149

Na Figura 213 ns vemos um exemplo do produto matricial de duas matrizes, obtido com o operador *, e que segue a frmula da lgebra linear para o produto de uma matriz de dimenses por uma matriz de dimenses , resultando em uma matriz de dimenses , onde = =1 .

-->x = [1 2; 3 4]; -->y = [10 20; 30 40]; -->x * y Produto ans = Matricial 70. 100. 150. 220. -->x .* y ans = Produto Elemento a 10. 40. Elemento 90. 160.
Figura 214: Produto matricial (*) versus produto elemento a elemento (.*) de duas matrizes

O Scilab emite uma mensagem de erro quando ocorre uma tentativa de multiplicao de matrizes com dimenses incompatveis com a operao. A Figura 214 mostra a diferena entre as operaes de produto matricial e produto elemento a elemento. -->x = [1 2 3; 4 5 6]; -->x * 2 ans = 2. 8.

4. 10.

6. 12.

-->x .* 2 ans = 2. 4. 8. 10.

6. 12.

Figura 215: Multiplicando uma matriz por um escalar

Uma matriz pode ser multiplicada por um escalar, caso em que os operadores * e .* so equivalentes, como mostrado na Figura 215.

6 - Matrizes
-->x = [1 2; 3 4]; -->x^2 Produto ans = Matricial x*x 7. 10. 15. 22. -->x .^ 2 ans = Exponenciao 1. 4. Elemento a 9. 16. Elemento
Figura 216: Exponenciao matricial (^) versus exponenciao elemento a elemento (.^)

150

Quanto exponenciao, o Scilab interpreta x^3 como x*x*x , ou seja como o produto matricial triplo da matriz x por ela mesma. o que s faz sentido quando x uma matriz quadrada. J x .^ 3 interpretado como x .* x .* x, ou seja, o produto triplo da matriz x por ela mesma, feito elemento a elemento, operao que pode ser feita com matrizes de dimenses arbitrrias. A Figura 216 mostra um exemplo da diferena entre as duas operaes. -->a = [1 2 3; 4 5 6] a = 1. 2. 3. 4. 5. 6. -->a' ans = 1. 2. 3.

4. 5. 6.

Figura 217: Transpondo uma matriz

Se a uma matriz, adesigna a matriz transposta de a, como mostrado na Figura 217. A = 4. 7. 6. 2. 2. 1. 1. 1. 6. -->IA = inv(A) IA = - 0.3333333 1.0909091 0.3333333 - 0.5454545 0. - 0.0909091

0.1515152 - 0.2424242 0.1818182

Figura 218: A funo inv, que produz a matriz inversa

A funo inv produz a matriz inversa da matriz dada como argumento. A Figura 218 mostra um exemplo de sua utilizao. Quando multiplicamos uma matriz por sua inversa esperamos obter a matriz identidade, mas no exatamente isso o que mostra a Figura 219.

6 - Matrizes -->A * IA ans = 1. 0. 1.110D-16 1. 5.551D-17 0. -->IA * A ans = 1. 8.327D-17 0. 1. 0. 0.

151

- 4.441D-16 - 1.110D-16 1. 0. 0. 1.

Figura 219: O produto de uma matriz por sua inversa calculada pelo Scilab pode ser ligeiramente diferente da matriz identidade

Ali vemos elementos no nulos fora da diagonal principal tanto de A * IA como de IA * A. Isso mais uma manifestao dos erros de arredondamento que ocorrem em operaes aritmticas de ponto flutuante. No caso, esses erros no so motivo de preocupao, pois os elementos no nulos fora da diagonal tm valor absoluto ordens de grandeza menores que os elementos das matrizes. Podemos usar a inversa de uma matriz para resolver um sistema de equaes lineares = onde, por exemplo, 2 1 3 = [ 2 1 1] 4 1 3 e 4 = [0] 1 Relembrando, podemos resolver a equao multiplicando os dois lados por 1: 1 = = = 1 onde a matriz identidade. Usando a console do Scilab, o sistema pode ser resolvido com a seqncia de operaes mostrada na Figura 220.

6 - Matrizes -->a = [-2 -2 3; 2 1 1;-4 1 3] a = - 2. - 1. 3. 2. 1. 1. - 4. 1. 3. -->b = [-4 0 1] b = - 4. 0. 1. -->x = inv(a)*b x = - 0.5 2. - 1.


Figura 220: Resolvendo um sistema de equaes lineares

152

A preciso do resultado pode ser avaliada calculando , o que pode ser feito no Scilab como mostrado na Figura 221. -->residuo = a*x - b residuo = 0. - 2.220D-16 0.
Figura 221: Calculando o erro numrico da soluo encontrada

6.3 Construindo matrizes


Vetores com valores regularmente espaados podem ser construdos como mostrado na Figura 222. -->x = 10:1:13 x = 10. 11. 12. -->x = 12:-0.5:10 x = 12. 11.5 11. -->x = 10:13 x = 10. 11. 12.

13. 10.5 13. 10.

Figura 222: Construo de vetores regulares

A forma geral <valor inicial>:<incremento>:<limite>. Repare que o incremento pode ser negativo, e que pode ser omitido quando for igual a 1, como no terceiro caso da Figura 222. Uma outra forma de se conseguir vetores com valores regularmente espaados com o uso da funo linspace(<valor inicial>, <valor final>, <nmero de pontos>), onde, alm do valor inicial e do valor final, fornecido o nmero de pontos em que se deseja dividir o intervalo, ao invs do valor do incremento. A Figura 223 mostra dois exemplos de uso da funo linspace.

6 - Matrizes

153

Nro. de Pontos
-->x = linspace(0,10,3) x = 0. 5. 10.

Limites

-->x = linspace(0,10,6) x = 0. 2. 4. 6.

8.

10.

Figura 223: Usando a funo linspace para construir vetores com valores regularmente espaados

Para se obter matrizes onde todos os elementos tm o valor 0 ou o valor 1, podem ser utilizadas as funes zeros e ones, como mostrado na Figura 224. -->x = zeros(2,3) x = 0. 0. 0. 0. 0. 0. -->y = ones(2,3) y = 1. 1. 1. 1. 1. 1.
Figura 224: Matrizes com todos os elementos iguais a 0 ou iguais a 1

Outra matriz que se pode obter a matriz identidade, atravs da funo eye, como vemos na Figura 225. -->I = eye(4,4) I = 1. 0. 0. 0. 1. 0. 0. 0. 1. 0. 0. 0.

0. 0. 0. 1.

Figura 225: Obtendo uma matriz identidade com a funo eye

Matrizes com elementos randmicos so muito teis para programas que fazem simulaes de eventos aleatrios, como a chegada de um carro em uma fila. A funo rand gera matrizes onde cada elemento um nmero entre 0 e 1, sorteado a cada chamada da funo. A Figura 226 mostra dois exemplos de uso desta funo.

6 - Matrizes

154

Gera nmeros aleatrios entre 0e1 -->m = rand(2,3) m = 0.2113249 0.7560439 -->n = rand(2,3) n = 0.8497452 0.6857310

Novos nmeros a cada chamada 0.0002211 0.3303271 0.6653811 0.6283918

0.8782165 0.0683740

0.5608486 0.6623569

Figura 226: Matrizes randmicas

Algumas vezes conveniente gerar matrizes aleatrias com valores inteiros entre, digamos, 0 e 100. Isto se faz com um comando como m = round(rand(2,3)*100), muito til para quem, como o autor destas linhas, necessita com freqncia de exemplos de matrizes com valores inteiros. A funo round retorna o inteiro mais prximo de seu argumento. -->x = [1 2; 3 4]; -->y = [10 20; 30 40]; -->z = [x y] z = 1. 2. 10. 20. 3. 4. 30. 40. -->z = [x ; y] z = 1. 2. 3. 4. 10. 20. 30. 40.
Figura 227: Construindo matrizes por justaposio de matrizes j existentes

possvel construir matrizes a partir de matrizes j existentes. Se x e y so matrizes, [x y] denota uma nova matriz, com y ao lado de x, e [x ; y] denota uma matriz com y abaixo de x, como mostrado na Figura 227.
-->sqrt([4 9 16 25]) ans =
2. 3. 4. 5.

Figura 228: Gerando um vetor como resultado da aplicao de uma funo elementar Scilab a um vetor

A Figura 228 mostra outra forma de se construir uma matriz a partir de uma matriz j existente, atravs da aplicao de uma funo elementar do Scilab a uma matriz. A matriz produzida tem as mesmas dimenses da matriz passada como argumento, e cada elemento resulta da aplicao da funo ao elemento correspondente da matriz original.

6.4 Matrizes e Grficos


Matrizes e vetores so imprescindveis para a construo de grficos no Scilab. O comando mais simples para a gerao de um grfico plot2d(x,y), onde x e y so vetores com o mesmo nmero de pontos. O Scilab constri um grfico unindo por segmentos de reta os pontos (x(1), y(1)), (x(2),y(2)) , e assim por diante at o ltimo par de pontos.

6 - Matrizes

155

-->x = [1 4 7 11]; y = [12 6 15 7]; -->plot2d(x,y)


15

7,15

14

13

1,12

12

11

10

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

Figura 229: Exemplo de grfico obtido com plot2d

A Figura 229 mostra um exemplo de grfico obtido com o comando plot2d; outro exemplo est na Figura 230, que mostra que poligonais arbitrrias podem ser traadas com plot2d. Uma infinidade de parmetros pode ser utilizada no comando plot2d, determinando cores e espessuras de linhas, tracejados, escalas, etc. Neste curso ns veremos apenas comandos bsicos; voc pode usar o help do Scilab para saber mais e obter um grfico com um acabamento melhor.

-->x = [2 5 3 4]; y = [ 3 1 4 7];

-->plot2d(x,y) 4,7

3,4 2,3

5,1
Figura 230: Outro exemplo de grfico obtido com plot2d

Para se obter um grfico da funo seno, podemos fazer como mostrado na Figura 231. Primeiramente gerado o vetor x de abscissas e, depois, o vetor y obtido pela aplicao da funo sin ao vetor x. O comando plot2d(x,y) gera o grfico.

6 - Matrizes
-->x = 0:0.8:3*%pi; -->y = sin(x); -->plot2d(x,y)
1.0 0.8 0.6 0.4

156

0.2

O espaamento de 0.8 est grande!

0.0 -0.2

-0.4 -0.6

-0.8 -1.0 0 1 2 3 4 5 6 7 8 9

Figura 231: Grfico da funo seno com espaamento excessivo

A curva obtida est toda quebrada, com cotovelos visveis. que, ao construirmos um grfico a partir de valores em vetores, estamos fazendo uma transformao digital-analgica adequada para consumo humano. No caso, o nmero de pontos utilizado para as abscissas foi pequeno para a nossa acuidade visual. Um resultado melhor (e que mostra que a gerao de um vetor pela funo linspace mais confortvel nessas ocasies) est mostrado na Figura 232.

-->x = linspace(0,3*%pi,101) -->y = sin(x); -->plot2d(x,y

Com 101 pontos temos uma curva mais suave

32

Figura 232: Grfico da funo seno com um espaamento agradvel

A funo plot2d pode ser usada para traar vrias curvas em um nico grfico. O comando plot2d(x,M) , onde x um vetor coluna, e M uma matriz com o mesmo nmero de linhas de x faz um grfico de x versus cada coluna de M.

6 - Matrizes
-->x = linspace(0, 3*%pi, 101)'; -->plot2d(x,[sin(x) sin(2*x) sin(3*x)])
1.0 0.8

157

0.6 0.4

0.2

0.0 -0.2

-0.4 -0.6

x um vetor coluna (e sin(x), sin(2*x) e sin(3*x) tambm so)


0 1 2 3 4 5 6 7 8 9 10

-0.8 -1.0

Figura 233: Grfico com vrias curvas obtido com plot2d

A Figura 233 mostra um grfico obtido dessa forma. Repare que o vetor x um vetor coluna, e que, como na Figura 227, a matriz cujas colunas so mostradas no grfico construda por justaposio dos vetores coluna sin(x) , sin(2*x) e sin(3*x).

6.5 Grficos 3D
Grficos tridimensionais podem ser produzidos no Scilab de muitas maneiras; o comando mais bsico o plot3d. Em sua forma mais simples, preciso gerar um vetor x, outro vetor y, e um valor para z para cada par (x(i),y(i)). Por exemplo, a execuo do programa da Figura 234 gera o grfico da Figura 235. x = linspace(-2*%pi,2*%pi,90); y = x; for i=1:length(x) for j=1:length(y) z(i,j) = sin(x(i))*cos(y(j)); end end plot3d(x,y,z)
Figura 234: Exemplo de uso de plot3d

Figura 235: (, ) = ()()

Se substituirmos a funo por z(i,j) = 10 -(x(i)^2 + y(j)^2), por exemplo, vamos obter o grfico da Figura 236.

6 - Matrizes

158

Figura 236: (, ) = ( + )

Grficos mais coloridos so obtidos com a funo plot3d1, que permite tambm a alterao do mapa de cores. Veja o exemplo do programa da Figura 237, que voc no precisa entender em detalhes para modific-lo conforme seu interesse. clear(); x = linspace(-2*%pi,2*%pi,60); y = x; for i=1:length(x) for j=1:length(y) z(i,j) = sin(x(i))*cos(y(j)); end end curFig = scf(3); plot3d1(x,y,z); cmap = curFig.color_map; curFig.color_map = autumncolormap(64); xtitle("f(x,y) = seno(x).cos(y)","Eixo x","Eixo y","Eixo z")
Figura 237: Exemplo de uso de plot3d1 com mapa de cores

6 - Matrizes

159

Figura 238: (, ) = ()() com plot3d1 e mapa de cores

Alm do autumncolormap, o Scilab oferece vrios outros mapas que associam valores a cores. Para descobri-los, bata help colormap na console do Scilab. A janela grfica permite tambm que voc gire o grfico com o mouse, conseguindo outras vises de seus dados. O grfico abaixo foi obtido utilizando este recurso de rotao.

Figura 239: Rotao do grfico da Figura 238

Estes so exemplos simples mas que podem ser teis em clculo e outras disciplinas. Existem infinitas combinaes de muitos e muitos parmetros que alteram a forma dos grficos, que voc pode pesquisar e experimentar no Scilab.

6.6 Matrizes de Strings


Matrizes podem ter strings como valores de seus elementos, como mostram os exemplos na Figura 240.

6 - Matrizes -->a = ["s1" "s2"] a = !s1 s2 ! -->b = ["s1" ; "s2"] b = !s1 ! ! ! !s2 !
Figura 240: Exemplos de matrizes de strings

160

Diversas funes oferecidas pelo Scilab tm vetores de strings como resultado, como a funo tokens, utilizada para obter partes de um strings separadas por um delimitador. Um exemplo de uso desta funo est na Figura 241.
-->tokens("C:\Users\Osvaldo\Dropbox\Ensino\dcc001\2012-2\Mdulo 06","\") ans = !C: ! !Users ! !Osvaldo ! !Dropbox ! !Ensino ! !dcc001 ! !2012-2 ! !Mdulo 06 ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! Figura 241: Exemplo de uso da funo tokens com delimitador "\"

Quando o caractere delimitador dos tokens o espao em branco, ele pode ser omitido na chamada, como mostra a Figura 242. -->t = tokens('Ouviram do Ipiranga as margens plcidas") t = !Ouviram ! !do ! !Ipiranga ! !as ! !margens ! !plcidas ! ! ! ! ! ! ! ! ! ! !

Figura 242: Exemplo de uso da funo tokens usando espao como separador

O ligeiro desalinhamento presente nos dois exemplos se deve a um bug do Scilab, que ocorre na exibio de strings com caracteres acentuados.

6 - Matrizes

161

6.7 Matrizes e Expresses Lgicas


O resultado de uma expresso relacional envolvendo matrizes uma matriz de valores booleanos que resultam da expresso aplicada elemento a elemento das matrizes, como mostram os exemplos na Figura 243. -->a = [3 7;8 2] a = 3. 7. 8. 2. -->a > 5 ans = F T T F -->a = [3 7; 8 2]; -->b = [5 6; 7 8]; -->a > b ans = F T T F

Figura 243: Expresses relacionais gerando matrizes booleanas

Uma expresso relacional envolvendo matrizes pode ser empregada em um comando if, mas isso deve ser feito com muito cuidado, pois a clusula then s ser executada se todos os elementos da matriz booleana resultante forem iguais a %t. A Figura 244 mostra um exemplo, onde somente o segundo if tem a sua clusula then executada, pois a matriz resultante da comparao a > 0 tem todos os elementos iguais a %t. -->a = [3 -->x = 0; -->if a > -->if a > -->[x y] ans = 0. 9; 12 1] y = 0; 5 then; x = 10000; end; 0 then; y = 10000; end; 10000.

Figura 244: Exemplos de emprego de expresses relacionais matriciais em comandos if

Se A for uma matriz e MB uma matriz booleana com as mesmas dimenses de A, A(MB) designa aqueles elementos de A com correspondentes em MB iguais a %t. -->A = [3 9; 12 1] A = 3. 9. 12. 1. -->MB = [%t %f; %f %t] MB = T F F T -->A(MB) = 0 A = 0. 9. 12. 0.
Figura 245: Uso de matriz booleana para seleo de elementos de uma matriz

Isso nos permite selecionar elementos de uma forma elegante, como mostra a Figura 246

6 - Matrizes -->a = [3 -->a(a>5) a = 3. - 1. 9; 12 1]; = -1 1. 1.

162

Figura 246: Exemplo de seleo de elementos de uma matriz por uma matriz booleana

7 - Loops

163

7 Loops
Loops so construes que voc pode colocar em um programa para prescrever comportamentos repetitivos em sua execuo. Loops so a essncia da programao: ns, programadores, trabalhamos pouco para constru-los; computadores podem trabalhar muito para execut-los. Veremos neste mdulo dois comandos para a programao de loops, os comandos while e for que, com algumas variaes, existem em praticamente todas as linguagens de programao.

7.1 O comando while


Como um primeiro exemplo vamos fazer um programa que, repetidamente, leia coeficientes de equaes de segundo grau e calcule suas razes. A cada equao processada, o programa deve interrogar o usurio sobre seu desejo de resolver mais uma equao. O processamento de cada equao deve ser igual ao produzido pelo programa da Figura 195. Um comportamento repetitivo pode ser obtido com o uso do comando while, que tem a seguinte forma: while <condio> <bloco de comandos> end Sua execuo resulta em repetidas execues dos comandos no <bloco de comandos> (que chamamos de corpo do loop), repetio que s se interrompe quando a expresso lgica <condio> no se verificar. Para transformarmos o programa no repetitivo em repetitivo, muitas vezes possvel seguir um padro como mostrado na Figura 247. continua = %T; while continua // Processamento de um item ... // Deciso decisao = ... input('Continua? (s/n)','string'); continua = decisao == 's'; end printf('\nObrigado!');
Figura 247: Padro de programa com loop controlado por uma ao do usurio

Aqui a <condio> do while uma expresso lgica dada pelo valor de uma nica varivel, a que demos o nome de continua. Seu valor inicial %t, o que garante uma primeira execuo do corpo do loop. Ao fim de cada execuo do corpo do loop, o usurio deve digitar 's' se desejar processar outro item, e 'n' seno (na verdade, qualquer string diferente de 's' serviria).

7 - Loops // Clculo das razes // de 2o grau continua = %t; while continua // Processamento de a = input("Digite o b = input("Digite o c = input("Digite o de diversas equaes

164

uma equao valor de a:"); valor de b:"); valor de c:");

delta = b^2 - 4*a*c if delta >= 0 then r1 = (-b+sqrt(delta))/(2*a); r2 = (-b-sqrt(delta))/(2*a); printf("As razes so %g e %g",r1,r2); else printf("As razes so complexas"); end // Deciso de continuao pelo usurio decisao = input("Outra equao? (s/n)","string"); continua = decisao == "s"; end printf("Obrigado, e volte sempre.")
Figura 248: Programa para clculo das razes de diversas equaes de 2o grau

O emprego do comando while deve ser feito com ateno, pois voc pode prescrever um loop que nunca ir parar, como no exemplo da Figura 249. O while s seria interrompido quando x for maior que 10, o que nunca acontecer porque x vale 0 inicialmente e, a cada passo, fica ainda menor (no Scilab voc pode interromper a execuo de um programa que aparenta estar em loop infinito atravs do menu Controle/Abortar). x = 0; while x <= 10 printf("\nx = %g", x) x = x - 0.2; end
Figura 249: Um loop infinito

7.2 Loop para o Clculo de Fatorial


Como um segundo exemplo de uso do comando while, vamos atacar o problema do clculo do fatorial de um nmero a ser lido em tempo de execuo. O Scilab oferece diretamente a funo factorial(n) que j faz este clculo, mas aqui ns vamos mostrar como calcular um fatorial fazendo uma multiplicao de cada vez, o que provavelmente feito pela implementao da funo factorial. Ns sabemos que ! = 1 2 = =1 , e que portanto teremos que realizar repetidas multiplicaes para obter o fatorial. Sabemos tambm que 0! = 1, e que ! = ( 1)! .

7 - Loops k = 1; fat = 1; // fat == (k-1)! while k <= n fat = fat * k; //== (k-1)! * k == k! k = k + 1; // fat == (k-1)! end // fat == (k-1)! e k == n+1 // portanto, fat == n!
Figura 250: Clculo de fatorial utilizando o comando while

165

J temos condies de compreender o cdigo mostrado na Figura 250, que utiliza duas variveis, fat e k. O objetivo obter fat tal que fat == n!. O raciocnio empregado se baseia essencialmente no fato de que, como possvel obter o fatorial de k multiplicando por k o fatorial de k-1, e como o fatorial de 0 igual a 1, podemos obter o fatorial de n por multiplicaes sucessivas de 1 por 1, 2, ..., n: Como preparao para a execuo do loop, as variveis k e fat so inicializadas com o valor 1. O loop construdo explorando a propriedade fat == (k-1)!, que estabelecida pela preparao do loop (dado que k == 1, e (k-1)! == 0! == 1 ), e restabelecida ao trmino de cada execuo do corpo do loop. A varivel k incrementada de 1 a cada passagem do loop. Quando o loop termina, temos k == n + 1, e como fat == (k-1)!, temos em fat o valor de n! , como queramos.

Em um loop, uma propriedade que vlida ao incio e ao trmino de cada execuo de seu corpo chamada de invariante do loop. Na Figura 250 a propriedade fat == (k-1)! um invariante do loop. Um exemplo de execuo deste loop est na Figura 251.
Invariante: fat sempre contm o fatorial de k-1

fat 1
A cada passo, fat multiplicado por k

24 120

k incrementado a cada passo

6
Valor de k que termina o loop quando n == 5

Valores iniciais colocados na preparao do loop

Figura 251: Exemplo de clculo do fatorial usando o loop da Figura 250

7.3 Loop para o Clculo da Soma dos Elementos de um Vetor


Como mais um exemplo, vamos explorar invariantes de loop para obter em uma varivel s a soma de todos os elementos de um vetor A com n elementos. No Scilab, isso pode ser feito diretamente pelo comando s = sum(A); a Figura 252 mostra como faz-lo utilizando um loop, fazendo uma soma de cada vez, como provavelmente implementada a funo sum.

7 - Loops s = 0; k = 1; // s == sum(A(1:k-1)), // lembrando que A(1:0) == [] while k <= n s = s + A(k); // s == sum(A(1:k)) k = k + 1; // s == sum(A(1:k-1)) end // s == sum(A(1:k-1)) e k == n+1 // portanto, s == sum(A(1:n))
Figura 252: Loop para soma dos elementos de um vetor

166

O objetivo obter s tal que s == sum(A), e o racioccinio empregado na construo do loop o seguinte: Como preparao para o loop, fazemos s = 0 e k = 1; O loop explora o invariante s == sum(A(1:k-1)) , que estabelecido pela preparao do loop (lembrando que A(1:0) == [] , a matriz vazia), e restabelecido ao trmino de cada execuo do corpo do loop; A varivel k incrementada de 1 a cada passagem do loop; Quando o loop termina, k == n + 1 , e como s == sum(A(1:k-1)) , temos s == sum(A(1:n)), como queramos.

k incrementado a cada passo

Valor de k que termina o loop quando n == 5

Valores iniciais colocados na preparao do loop

Em cada passo, A(i) somado a s

0
+

5
+

7
+

16 19 24
+ +

Invariante: s sempre contm a soma de todos os elementos esquerda de A(k)

Figura 253: Exemplo de clculo da soma dos elementos de um vetor pelo loop da Figura 252

7.4 Loop para encontrar o Menor Valor presente em um Vetor


Como mais um exemplo, vamos mostrar um loop que atribui a uma varivel m o menor valor presente em um vetor A de n elementos, o que poderia ser feito no Scilab com o comando m = min(A). m = A(1); k = 2; // m == min(A(1:k-1)) while k <= n if A(k) < m then m = A(k); end // m == min(A(1:k)) k = k + 1; // m == min(A(1:k-1))

7 - Loops end // m == min(A(1:k-1)) e k == n + 1; // portanto, m = min(A(1:n))


Figura 254: Loop para encontrar o menor valor presente em um vetor

167

Nosso objetivo obter m tal que m == min(A); a lgica empregada na construo do loop a seguinte: Como preparao para o loop, fazemos m = A(1) e k = 2; O loop explora o invariante m == min(A(1:k-1)), que estabelecido pela preparao do loop (pois A(1) == min(A(1:1))), e restabelecido ao trmino de cada execuo do corpo do loop; A varivel k incrementada de 1 a cada passagem do loop; Quando o loop termina, k == n + 1, e como m == min(A(1:k-1)), temos m == min(A(1:n)) , como queramos.

Um exemplo de execuo deste loop est na Figura 255.

k
k incrementado a cada passo

Valor de k que termina o loop quando n == 5

Valores iniciais colocados na preparao do loop

m
Em cada passo, o valor de m substitudo por min(m,A(k))

7
<

5
<

5
<

3
<

3
Invariante: m sempre contm o menor entre todos os elementos entre A(1) e A(k-1)

10

Figura 255: Exemplo de determinao do menor valor presente em um vetor usando o loop da Figura 254

7.5 Loop para encontrar o Mximo Divisor Comum usando o Algoritmo de Euclides
Como ainda outro exemplo de uso do comando while, vamos apresentar o algoritmo de Euclides, proposto em ... 300 A.C. e que utilizado at hoje45! Este algoritmo encontra o mximo divisor comum de dois inteiros positivos. Por definio, (, ) onde e so inteiros positivos, o maior dentre todos os divisores comuns a e . O algoritmo se baseia no fato de que se substituirmos o maior dentre e pela diferena entre e , o mximo divisor comum no se altera. A prova desta propriedade no difcil. Queremos mostrar que se = (, ) e > , ento = (( ), ). Parte 1: Se = (, ) ento tambm divide Se um divisor de , ento = . onde 1 um inteiro. Mas tambm um divisor de , e portanto = .
45

Euclidean algorithm - Wikipedia, the free encyclopedia, acessado 8 de maro de 2011, http://en.wikipedia.org/wiki/Euclidean_algorithm#cite_note-2.

7 - Loops onde 1 um inteiro. Temos ento = ( )

168

supondo que > , ou > . Ou seja, se um divisor de e de , tambm um divisor de . Parte 2: Se = (, ) ento o maior dentre os divisores de ( ) e . Suponhamos que exista > tal que ( ) = . e = . ; teremos . = . ou = . ( + ) seria portanto divisor de e de e, como > por hiptese, e seria maior que (, ), o que contradiz a definio de mximo divisor comum Sabemos tambm que (, ) = , para qualquer inteiro positivo. Com isso podemos construir o programa da Figura 256. m = input("m = "); n = input("n = "); a = m; b = n; // a, b inteiros; a > 0, b > 0; // mdc(a,b) == mdc(m,n) while a ~= b if a > b then a = a - b; else b = b - a; end // mdc(a,b) == mdc(m,n) // a, b inteiros; a > 0, b > 0; end // mdc(a,b) == mdc(m,n) // a, b inteiros; a > 0, b > 0; // Como a == b, mdc(a,b) == a == b == mdc(m,n) printf("MDC(%d,%d) = %d",m,n,a)
Figura 256: Programa para clculo do mximo divisor comum pelo algoritmo de Euclides

A construo deste loop emprega a seguinte lgica: na preparao do loop os comandos a = m e b = n, estabelecem trivialmente o invariante do loop, mdc(a,b) == mdc(m,n), a > 0 e b > 0 (supondo que m > 0 e n > 0) a cada passo, se a for maior que b, seu valor substitudo por a - b, e se b for maior do que a, seu valor substitudo por b a. Nos dois casos o invariante mantido, em vista do que demonstramos acima e do fato de estarmos subtraindo de um nmero um valor positivo menor que ele; quando o loop termina, temos a == b, e portanto a (ou b, claro) contm o valor desejado do mdc(m,n).

A Figura 257 mostra um exemplo de execuo deste loop.

7 - Loops
Invariante: a>0, b>0 MDC(a,b) = MDC(m,n)

169

m n

56 12

56

44

32

20

b 12 12
Valores iniciais colocados na preparao do loop

12

12

12

4
O loop termina quando a = b

Em cada passo, o maior entre a e b substitudo pela diferena

Figura 257: Exemplo de loop para clculo do mximo divisor comum

7.6 O comando for


Loops como o da Figura 250 so to freqentes em programao que existe um outro comando, o for, que substitui o comando while com vantagens em alguns casos. Na Figura 258 ns vemos um programa que tambm calcula o fatorial de um nmero, utilizando o comando for. // Clculo do fatorial de um nmero // Leitura do nmero n = input("n = "); // Clculo do fatorial fat = 1; for k = 1:n fat = fat * k; end // Impresso do resultado printf("O fatorial de %d %d",n,fat)
Figura 258: Clculo de fatorial utilizando o comando for

A simplificao com relao verso com while vem da inicializao da varivel k com o valor 1 e da condio de parada, implcitas no comando for k = 1:n. Tambm implcito neste for est o comando k = k + 1. A forma geral de um comando for est mostrada na Figura 259. for <varivel> = <vetor> <bloco for>; End
Figura 259: Forma geral de um comando for

Aqui <vetor> contm os valores atribudos varivel indexadora <varivel> a cada iterao do loop.

7 - Loops

170

for i = 1:2:10 printf('\ni = %g',i); end


i i i i i
No exemplo da Figura 260, A varivel indexadora i; O vetor de valores 1:2:10 igual a [1 3 5 7 9]; so estes os valores que i assumir a cada execuo do corpo do loop. O \n na frase do comando printf uma sequncia de escape, isto , uma codificao em caracteres imprimveis de um caracter no imprimvel no caso, Line Feed, que produz uma nova linha na sada.

= = = = =

1 3 5 7 9

i varia de 2 em 2 Sada Repare que i no assumiu o limite superior do loop

Figura 260: Exemplo de comando for com passo diferente de 1

for i = 20:-2:16 printf('\ni = %g',i); end


i = 20 i = 18 i = 16
Sada

Figura 261: Exemplo de for com passo negativo

O passo de um for pode ser negativo, como mostrado na Figura 261, e a varivel de controle pode assumir valores no inteiros, como na Figura 262.
A varivel de controle pode assumir valores no inteiros

for x = 0:0.3:0.7 printf(' \nx = %g',x); end

x = 0 x = 0.3 x = 0.6

Sada

Figura 262: Exemplo de for com a varivel de controle assumindo valores no inteiros

7.7 Gerao e Impresso de Tabelas

7 - Loops x 0.0 0.2 0.4 0.6 0.8 seno(x) 0.0000 0.1987 0.3894 0.5646 0.8415

171

Figura 263: Tabela de Senos

Vamos agora usar o comando for para a construo de uma tabela como a da Figura 263 , com x variando de 0 a 2, de 0.2 em 0.2, e vamos aproveitar a oportunidade para aprender mais sobre o controle de sada com o comando printf. // Tabela da funo Seno for x = 0:0.2:2*%pi printf("%g %g",x, sin(x)) end
Figura 264: O programa Tabela_de_Senos_1.sce

O programa da Figura 264 parece atender especificao, mas quando executado pelo Scilab produz uma sada de difcil compreenso, como mostrado na Figura 265. --> 0 00.2 0.1986690.4 0.3894180.6 0.5646420.8 0.7173561 0.841471
Figura 265: Primeiros caracteres da sada do programa Tabela_de_Senos_1.sce

Um primeiro problema a corrigir a separao em linhas, o que pode ser obtido usando a sequncia de escape \n na frase do comando printf. Com isso ns chegamos ao programa Tabela_de_Senos_2.sce, mostrado na Figura 266. // Tabela da funo Seno for x = 0:0.2:2*%pi printf("\n%g %g",x, sin(x)) end
Figura 266: O programa Tabela_de_Senos_2.sceFigura 263

A sada do Tabela_de_Senos_2.sce, cujas primeiras linhas esto mostradas na Figura 267, melhorou, mas ainda no est satisfatria. 0 0 0.2 0.198669 0.4 0.389418 0.6 0.564642 0.8 0.717356 1 0.841471 1.2 0.932039
Figura 267: Sada do programa Tabela_de_Senos_2.sce

Os problemas de alinhamento so causados pelo uso do cdigo de formato %g, que no especifica o nmero de colunas que um nmero ir ocupar. O nmero de colunas igual ao nmero de caracteres com a fonte tipogrfica no proporcional usada pelo Scilab, onde todas as letras ocupam o mesmo espao. Com uma fonte proporcional, como esta que voc est

7 - Loops

172

lendo, um i ocupa um espao menor do que um m, o que bem visvel quando comparamos iiii com mmmm. // Tabela da funo Seno // Impresso do cabealho printf("\n x seno(x)") // Impresso das linhas da tabela for x = 0:0.2:2*%pi printf("\n%3.1f %7.4f",x, sin(x)) end
Figura 268: O programa Tabela_de_Senos_3.sce

A Figura 268 mostra o programa Tabela_de_Senos_3.sce que produz a sada mostrada parcialmente na Figura 269. x 0.0 0.2 0.4 0.6 0.8 1.0 1.2 Nessa ltima verso, impressa uma linha com cabealhos para a tabela Para a formatao de x usado o cdigo %3.1f, que especifica um campo ocupando 3 colunas ao todo na impresso, com 1 casa decimal; Para a formatao de sin(x), o cdigo %7.4f especifica um campo com um total de 7 colunas, com 4 casas decimais. seno(x) 0.0000 0.1987 0.3894 0.5646 0.7174 0.8415 0.9320

Figura 269: Primeiras linhas da sada do programa Tabela_de_Senos_3.sce

Todo comando for pode ser substitudo por um comando while; a Figura 270 mostra outro exemplo dessa substituio. O inverso no verdadeiro: nem todo loop com while pode ser substitudo com facilidade por um loop com o comando for, como o caso do algoritmo de Euclides. x = 0; while x <= 2*%pi printf("\n%3.1f %7.4f",... x, sin(x)) x = x+0.2; end

for x = 0:0.2:2*%pi printf("\n%3.1f %7.4f",... x, sin(x)) end

Figura 270: Mesmo loop obtido com comandos for e while

7 - Loops

173

7.8 Comandos Aninhados


Blocos de comandos definidos por comandos como if e for podem conter qualquer tipo de comando, incluindo comandos de atribuio, de entrada e/ou sada, mas tambm outros ifs e outros for. Este aninhamento de comandos proporciona uma grande flexibilidade para o programador. Para ilustrar o uso de ifs aninhados vamos agora desenvolver um programa que: Leia o nome do aluno, que responde, por exemplo, Paulo; Leia tambm o total de pontos obtidos pelo aluno; Imprima, conforme o caso, a frase <aluno>, com <pontos> voc obteve o conceito X!, onde X determinado pela Tabela 3. Exemplos seriam Paulo, com 81 pontos voc obteve o conceitoB!, ou Paulo, com 90 pontos voc obteve o conceito A!
Tabela 3: Pontos e Conceitos

Pontos 90 100 80 < 90 70 < 80 60 < 70 40 < 60 0 < 40

Conceito A B C D E F

O programa PontosConceito.sce, apresentado na Figura 271, atende a esta especificao, acrescida da suposio de que o usurio ir digitar sempre valores entre 0 e 100. Neste programa voc deve observar que: A leitura do nome e dos pontos do aluno idntica utilizada no programa PassouNaoPassou.sce; Se o <bloco seno> do primeiro if chegar a ser executado, porque temos Pontos < 90, e por isto basta verificar que Pontos >= 80 para concluir que o conceito B; Se o <bloco seno> do segundo if chegar a ser executado, porque temos Pontos < 80, e por isso basta verificar que Pontos >= 70 para concluir que o conceito C; O mesmo raciocnio se aplica aos outros ifs, at o mais interno, onde o <bloco seno> no necessita de mais testes para concluir que o conceito F. Detalhe, mas muito til: o printf no fim do programa ilustra o uso de ... para indicar ao Scilab que um comando se prolonga por mais uma linha.

7 - Loops // Leitura do nome do aluno Nome = input("Seu nome, por favor:"); // Leitura dos pontos obtidos Pontos = input(Nome + ", quantos pontos voc conseguiu?"); // Determinao do conceito if Pontos >= 90 then Conceito = "A"; else if Pontos >= 80 then Conceito = "B"; else if Pontos >= 70 then Conceito = "C"; else if Pontos >= 60 then Conceito = "D"; else if Pontos >= 40 then Conceito = "E" else Conceito = "F" end end end end end printf("%s, com %g pontos voc obteve o conceito %s!",... Nome, Pontos, Conceito)
Figura 271: O programa PontosConceito.sce

174

Como j dissemos e continuaremos a dizer ao longo desse curso, programas so feitos para serem executados por computadores, mas tambm para serem lidos por humanos. Ao fazer um programa voc deve se preocupar com a sua legibilidade, tanto por outras pessoas que venham a trabalhar com ele, como com voc mesmo, algum tempo depois de t-lo escrito. A disposio grfica dos comandos em um programa tem grande influncia em sua legibilidade.Talvez voc j tenha reparado que o prprio editor SciNotes faz com que os blocos nos comandos if e for sempre apaream ligeiramente deslocados para a direita, com relao posio do comando que os delimita. Isso porque, com esse deslocamento, a identificao do comeo e do fim de cada bloco fica muito facilitada, e os possveis fluxos de execuo se tornam mais claros para ns.

7 - Loops
if delta < 0 then printf('Razes complexas!'); else r1 = (-b + sqrt(delta))/(2*a); r2 = (-b - sqrt(delta))/(2*a); printf('r1=%g e r2=%g.',r1,r2) end

175

Mais legvel

if delta < 0 then printf('Razes complexas!'); else r1 = (-b + sqrt(delta))/(2*a); r2 = (-b - sqrt(delta))/(2*a); printf('r1=%g e r2=%g.',r1,r2) end

Menos legvel

Figura 272: Ifs equivalentes para o Scilab, mas com diferenas de legibilidade devido indentao

Indentao o termo empregado para esta prtica de deslocamento de blocos internos na disposio grfica de um programa. Seu emprego visto como absolutamente essencial por toda a indstria de desenvolvimento de software. A Figura 272 e a Figura 273 mostram comparaes entre comandos digitados com e sem o emprego de indentao.

if Nota >= 90 then Conceito = 'A'; else if Nota >= 80 then Conceito = 'B'; else if Nota >= 70 then Conceito = 'C'; else if Nota >= 60 then Conceito = 'D'; else if Nota >= 40 then Conceito = E'; else Conceito = F; end end end end end

if Nota >= Conceito = else if Nota >= Conceito = else if Nota >= Conceito = else if Nota >= Conceito = else if Nota >= Conceito = else Conceito = end end end end end

90 then 'A'; 80 then 'B'; 70 then 'C'; 60 then 'D';

40 then E'; F;

Figura 273: Outro exemplo da influncia da indentao na legibilidade de um comando

7.9 Gerao e Impresso de uma Tabuada de Multiplicao


Vamos agora desenvolver um programa que produza uma tabuada de multiplicao, como mostrado na Figura 274.

7 - Loops
1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 3 6 9 12 15 18 21 24 27 4 8 12 16 20 24 28 32 36 5 10 15 20 25 30 35 40 45 6 12 18 24 30 36 42 48 54 7 14 21 28 35 42 49 56 63 8 16 24 32 40 48 56 64 72 9 18 27 36 45 54 63 72 81

176

Figura 274: Tabuada de Multiplicao

Um problema como este se resolve com dois for aninhados: um externo, para as linhas, e um interno, para as colunas de cada linha, o que feito pelo programa Tabuada1.sce, mostrado na Figura 275. // Tabuada de multiplicao for linha = 1:9 for coluna = 1:9 printf("%g",linha*coluna); end end
Figura 275: O programa Tabuada1.sce

Ao executar este programa verificamos entretanto que sua sada est ininteligvel: 12345678924681012141618369121518212... formando uma longa sequncia de algarismos sem separao, todos em uma nica linha. O que houve? Esquecemos de orientar o Scilab para mudar de linha, e tambm para, dentro de cada linha, separar cada coluna. // Tabuada de multiplicao for linha = 1:9 for coluna = 1:9 printf("%3g",linha*coluna); end printf("\n"); end
Figura 276: O programa Tabuada2.sce

O programa Tabuada2.sce resolve estes problemas, com a insero de um printf("\n"), executado ao trmino da impresso de cada linha, e com o cdigo de formato %3g que fixa 3 colunas para a impresso de cada produto.

7.10 Arquivos
Arquivos so unidades de armazenamento de dados no-volteis, que sistemas operacionais como Windows ou Linux permitem que sejam recuperados pelo nome e pela posio em uma organizao hierrquica de diretrios. Um arquivo criado por um programa, e pode ser lido e modificado por outros programas, programas que muitas vezes so executados em outros computadores. Arquivos so imprescindveis para o tratamento de grandes volumes de dados. Operaes fundamentais com arquivos que podem ser realizadas por programas so:

7 - Loops a leitura, que consiste na atribuio a variveis de valores presentes no arquivo, e a escrita, que consiste na gravao no arquivo de valores de variveis.

177

Existem muitos tipos de arquivos que podem ser manipulados por programas Scilab, mas neste curso iremos aprender somente a trabalhar com arquivos de texto, isto , arquivos que normalmente so legveis por humanos, e que podem ser editados usando programas como o Bloco de Notas do Windows. Um comando muito til para localizao de arquivos no Scilab o uigetfile, que permite ao usurio selecionar um arquivo navegando nos diretrios do sistema operacional. A Figura 277 mostra a janela de navegao para escolha de um arquivo aberta no Windows Vista aps a execuo de um comando uigetfile.

Figura 277: Janela de navegao e escolha de arquivos produzida com o comando uigetfile

O usurio pode escolher um entre os nomes de arquivos listados na janela, ou optar por um novo nome para um arquivo ainda no existente. O comando uigetfile retorna um string com a rota completa isto , desde o diretrio raiz do arquivo escolhido. Isso pode resultar em strings longos como o atribudo varivel f na Figura 278.
-->f = uigetfile(title="Escolha um arquivo:") f = C:\Users\Osvaldo\Documents\dcc\Ensino\dcc001\Scilab\Dados\ConstrCivil.txt Figura 278: String com rota completa obtido com uigetfile

Outras formas de uso do comando uigetfile so: Arq = uigetfile() o Mais simples para programar, mas nem to bom para o usurio; Arq = uigetfile("*.txt",pwd(),"Escolha um arquivo") o Um pouco mais complicado, porm pode oferecer mais conforto para o usurio, pois: o S so mostrados os arquivos selecionados por um filtro; no caso, o filtro "*.txt", que seleciona somente arquivos com terminao .txt, e

7 - Loops o o

178 a janela de escolha do arquivo tem o ttulo "Escolha um arquivo" , e exibe inicialmente o diretrio corrente do Scilab, o que pode evitar um aborrecido trabalho de navegao na estrutura de diretrios. A funo pwd() retorna o diretrio corrente do Scilab.

Outros comandos teis so o uigetdir, que serve para a localizao de diretrios, e o listfiles, que retorna um vetor de strings com os nomes de todos os arquivos em um diretrio. A Figura 279 um exemplo de uso conjunto destes dois comandos. -->d = uigetdir() d = C:\Documents and Settings\osvaldo\My Doc uments\My Dropbox\Ensino\dcc001\201 2-2\Mdulo 05 -->arquivos =listfiles(d) arquivos = !Mdulo5-2012-2.pptx ! !Mdulo5-2012-2.pdf ! !Mdulo 05.zip ! !Eq2g3.sce ! !Eq2g2.sce ! !Eq2g1.sce ! !Eq2g.sce ! ! ! ! ! ! ! ! ! ! ! ! !

Figura 279: Exemplo de uso dos comandos uigetdir e listfiles

7.11 Matrizes de Strings e Arquivos


possvel ler um arquivo e transformar todas as suas linhas em um vetor coluna de strings, cada uma de suas linhas sendo lida em um elemento do vetor. Para isso deve ser usado o comando mgetl(f), onde f um nome de arquivo, normalmente obtido com uigetfile. f = uigetfile(); linhas = mgetl(f);
Figura 280: Leitura de um arquivo como um vetor coluna de strings usando o comando mgetl

A Figura 280 mostra um uso tpico do comando mgetl, precedido pela localizao e da abertura do arquivo, e seguido pelo fechamento do arquivo.

7 - Loops
-->linhas linhas = !E agora, Jos? !A festa acabou, !a luz apagou, !o povo sumiu, !a noite esfriou, !e agora, Jos? !e agora, voc? !voc que sem nome, !que zomba dos outros, !voc que faz versos, !que ama, protesta? !e agora, Jos?

179

! ! ! ! ! ! ! ! ! ! ! !

Figura 281: Arquivo fonte visto com o Bloco de Notas e vetor de strings obtido com o comando mgetl

Na Figura 281 ns vemos o efeito desses comandos quando o arquivo escolhido para leitura o mostrado na parte esquerda da figura, com o famoso poema do Drummond.

7.12 Matrizes Numricas e Arquivos


O Scilab oferece os comandos fscanfMat e fprintfMat que permitem a leitura e a gravao de matrizes em arquivos . Estes comandos s podem ser usados para arquivos que contm ou contero somente nmeros em formato tabular, com exceo das primeiras linhas que podem conter textos. Os arquivos so lidos ou gravados com uma nica execuo desses comandos, que dispensam as operaes de abertura e de fechamento de arquivos. O comando fprintfMat(arq, M, "%5.2f", Cabecalho) grava a matriz numrica M no arquivo cujo nome o valor (string) de arq. Esse arquivo em suas primeiras linhas ir conter os strings que so os elementos do vetor coluna de strings chamado Cabecalho. Cada elemento de M gravado com o formato "%5.2f". O vetor Cabecalho normalmente usado para uma explicao sobre os campos presentes no arquivo. a = [1 2 3; 4 5 6; 7 8 9]; arq = uigetfile(); Cabecalho = [" Meus Dados "; "Col1 Col2 Col3"] fprintfMat(arq,a,"%5.2f",Cabecalho);
Figura 282: Gravao de uma matriz em um arquivo com fprintfMat

Na Figura 282 ns vemos um exemplo de uso do comando fprintfMat. O resultado deste programa um arquivo como o mostrado na Figura 283.

Figura 283: Arquivo gerado pelo programa da Figura 282

Se agora executarmos o programa da Figura 284, escolhendo como entrada o arquivo da Figura 283, iremos obter uma matriz m idntica matriz a gravada anteriormente.

7 - Loops

180

arquivo = uigetfile(); m = fscanfMat(arquivo)


Figura 284: Leitura de uma matriz com o comand fscanfMat

Vamos agora ver um exemplo de aplicao de matrizes e arquivos. A Figura 285 mostra o arquivo TempoBHZ.txt exibido com o Bloco de Notas. Cada linha do arquivo contm o nmero de um ms, a temperatura mdia mxima do ms, a temperatura mnima mdia, a mxima record, a mnima record, e a precipitao do ms em milmetros de chuva.

Figura 285: O arquivo TempoBHZ.txt

Ns queremos fazer um programa que: Leia os dados desse arquivo; Extraia desses dados vetores correspondentes a cada uma das colunas, conforme a Figura 285; Gere um grfico que exiba simultaneamente as curvas de mxima mdia, mnima mdia, mxima record e mnima record.

Examinando o arquivo de entrada ns vemos que ele tem um formato adequado para leitura com fscanfMat, pois tem uma linha de cabealho, e os dados restantes so todos numricos e dispostos em um formato tabular. arqClima = uigetfile(); ClimaBH = fscanfMat(arqClima); MaxMed = ClimaBH(:,2); // MaxMed = 2a coluna MinMed = ClimaBH(:,3); // MinMed = 3a coluna MaxRec = ClimaBH(:,4); // MaxRec = 4a coluna MinRec = ClimaBH(:,5); // MinRec = 5a coluna Precip = ClimaBH(:,6); // Precip = 6a coluna plot2d([1:12],[MaxMed MinMed MaxRec MinRec],... leg="MaxMed@MinMed@MaxRec@MinRec") xtitle("Temperaturas Mensais em BH","Ms","Graus C");
Figura 286: O programa ClimaBHZ.sce

A Figura 286 mostra o programa ClimaBHZ.sce que atende a essa especificao. Como voc pode ver, o programa bastante simples, com a descoberta e leitura do arquivo, seguida das extraes das colunas, e seguida da gerao do grfico. to simples que aproveitamos para introduzir duas novas tcnicas que podem melhorar a apresentao de um grfico:

7 - Loops

181

o parmetro extra de plot2d, leg="MaxMed@MinMed@MaxRec@MinRec", que gera legendas para cada curva em no grfico, e o comando xtitle, que determina ttulos para o grfico e para cada um dos eixos.
Temperaturas Mensais em BH 40

35

30

25
Graus C

20

15

10

0 0 2 MaxMed MinMed MaxRec 4 6 Ms 8 MinRec 10 12

Figura 287: Grfico gerado pelo programa da Figura 286 Na

Figura 287 voc pode ver o efeito destas tcnicas sobre o grfico.

7.13 Desenhando Mapas


Para se desenhar um polgono usando o Scilab basta colocar as coordenadas de seus vrtices em vetores x e y de mesmo tamanho, e executar plot2d(x,y). Por exemplo, a sequncia de comandos executados na console do Scilab --> x = [1 2 3 4 2 1]; --> y = [1 2 1 2 4 1]; --> plot2d(x,y,rect=[0 0 6 6]); (onde o parmetro rect indica as coordenadas de um retngulo que determina os limites de exibio) produz o grfico mostrado na Figura 288.

7 - Loops
6

182

0 0 1 2 3 4 5 6

Figura 288: Um polgono

Se quisermos acrescentar outro polgono, podemos fazer --> w = [4 5 5 4]; --> z = [0.5 0.5 1.5 0.5]; --> plot2d(w,z); obtendo o grfico mostrado na Figura 289.
6

0 0 1 2 3 4 5 6

Figura 289: Dois polgonos

Repare que foram utilizados dois pares de vetores, um para cada polgono desenhado. Quando temos muitos polgonos a desenhar, como o caso do mapa que faremos em seguida, torna-se interessante representar todos os polgonos em um nico par de vetores com as coordenadas de todos os vrtices, com a exibio feita por um nico comando plot2d. preciso entretanto encontrar um meio de informar ao Scilab quais so os pontos que separam dois polgonos. Isto porque se fizermos --> X = [x w]; --> Y = [y z]; --> plot2d(X,Y,rect=[0 0 6 6]); vamos obter o desenho da Figura 290, onde o ponto final do primeiro polgono e o ponto inicial do segundo polgono foram (naturalmente) emendados pelo Scilab.

7 - Loops

183

0 0 1 2 3 4 5 6

Figura 290: Efeito no desejado ao traar dois polgonos

Este problema resolvido inserindo-se pares de pontos com coordenadas iguais a %nan (representao de not a number em ponto flutuante; veja a Seo 2.1) para indicar ao Scilab os pontos de separao entre dois polgonos. Experimente agora fazer, na console do Scilab, --> X = [x %nan w]; --> Y = [y %nan z]; --> clf --> plot2d(X,Y,rect=[0 0 6 6]); e voc obter a figura desejada, com polgonos separados. O comando clf limpa a janela grfica do Scilab. Um mapa simples pode ser representado por uma tabela de pares latitude-longitude. Em princpio estas tabelas podem ser utilizadas diretamente para o desenho dos mapas utilizando a funo plot2d, mas, como j vimos, necessrio algum mecanismo para separar os polgonos isolados representando cada ilha, lago ou continente. No nosso site voc pode encontrar o arquivo world.txt (que obtivemos na referncia 46, e de onde retiramos grande parte desta seo). Se voc abrir este arquivo com um editor de arquivos texto como o PSPad47 (o Bloco de Notas serviria, mas para trabalhar com arquivos texto, ns preferimos o PSPad porque ele possibilita um maior controle sobre formatos e codificaes UTF-8, Windows, etc.), voc ver que o valor 9999 foi utilizado como codificao para a separao de polgonos.

46

Applications with Scilab, Maxima, Geogebra, acessado 28 de setembro de 2011, http://www.wolffdata.se/. 47 Download PSPad - free unicode developer editor, handles near any syntax like HTML, PHP, XHTML, JavaScript, ASP, Perl, C and many other languages with HEX editor, multilanguage interface, acessado 6 de maro de 2013, http://www.pspad.com/en/download.php.

7 - Loops

184

Figura 291: Arquivo world.txt aberto com o editor PSPad

e abra-o utilizando o Bloco de Notas (Notepad). Um pequeno exame desse arquivo basta para verificar que a separao entre os polgonos est ali representada pelas coordenadas com valores 9999. Isso se deve a uma restrio do comando fscanfMat, que s capaz de ler nmeros. Faa agora um programa que 1) Leia este arquivo em uma matriz Mapas. Use para isto as funes uigetfile e fscanfMat. 2) Extraia desta matriz dois vetores, Lat e Long, correspondendo s duas colunas da matriz lida. 3) Substitua nos vetores Lat e Long os valores 9999 por %nan. 4) Use plot2d para obter o desenho do mapa representado no arquivo.

8 - Funes

185

8 Funes
Funes so: uma ferramenta de modularizao da mais alta importncia para a programao, e um mecanismo lingustico para a prescrio de comportamentos repetitivos.

Vamos inicialmente mostrar o valor de funes como ferramenta de modularizao, o que permite o reaproveitamento de cdigo, a diviso de tarefas em projetos maiores de programao, e torna programas mais legveis.

8.1 Funes e Reaproveitamento de Cdigo


Para ilustrar o uso de funes, vamos desenvolver um programa que l dois inteiros, e , e que calcula e imprime o nmero de combinaes de elementos tomados a , dado pela frmula ! ( )= ( )! ! Temos trs fatoriais a calcular, e para isso, vamos procurar reaproveitar o cdigo que conhecemos para o clculo do fatorial, mostrado na Figura 292. fat = 1; for i = 1:n fat = fat*i; end
Figura 292: Trecho de cdigo para o clculo do fatorial

A adaptao deste cdigo aos trs fatoriais necessrios para o clculo do nmero de combinaes nos leva ao programa mostrado na Figura 293, onde cada clculo de fatorial est destacado, e onde o comando de sada foi omitido.

n=input("n="); k=input("k="); fat_n = 1; // Clculo do fatorial de n for i = 2:n fat_n = fat_n * i; end fat_n_k = 1; // Clculo do fatorial de n-k for i = 2:(n-k) fat_n_k = fat_n_k * i; end fat_k = 1; // Clculo do fatorial de k for i = 2:k fat_k = fat_k * i; end nComb = fat_n/(fat_n_k * fat_k)
Figura 293: Programa para clculo do nmero de combinaes de n k a k

8 - Funes

186

Voc deve reparar que foram feitas trs adaptaes do cdigo, uma para cada fatorial a ser calculado. Ns vamos procurar mostrar que com o uso de funes este programa se torna muito mais claro. Para isso vamos dividir o programa em duas partes: o programa principal e a funo. function fat = fatorial(v) fat = 1; for i = 1:v fat = fat*i end endfunction
Figura 294: Cdigo da funo fatorial

//Combinaes de n k a k exec("fatorial.sci"); n = input("n = "); k = input("k = "); fat_n = fatorial(n); fat_k = fatorial(k); fat_n_k = fatorial(n-k); Comb_n_k = fat_n/(fat_k * fat_n_k); printf("Comb(%d,%d) = %d",n,k,Comb_n_k)
Figura 295: Cdigo do programa principal para clculo do nmero de combinaes de n k a k

O comando exec um detalhe tcnico: serve para indicar ao Scilab que a funo fatorial ser utilizada pelo programa. O programa da Figura 295 faz a mesma coisa que o da Figura 293, mas ao invs de conter trs trechos de cdigo para o clculo dos fatoriais, contm trs chamadas da funo fatorial, e um nico cdigo para esta funo, mostrado na Figura 296. O cdigo na Figura 295 recebe a designao de programa principal. A execuo de um programa com funes se inicia pelo programa principal. A execuo de uma chamada transfere o controle para a funo; ao trmino da execuo da funo, o controle devolvido para o ponto de chamada, em uma operao que chamamos de retorno da funo. O efeito das adaptaes usadas para os diferentes fatoriais obtido pelo uso de diferentes parmetros da funo a cada chamada, o que propicia um reaproveitamento de cdigo muito mais elegante. A leitura do programa principal tambm muito mais fcil, pois a inteno do programador se torna mais clara. Para algum que no tivesse construdo o programa da Figura 293, a percepo da similaridade entre os trechos de clculo do fatorial pode no ser bvia, e requer esforo de verificao. Para o prprio programador, as substituies utilizadas para a construo do programa da Figura 293 so uma fonte de enganos. O clculo de combinaes uma operao que pode ser aproveitada em outras ocasies. Como vimos, o cdigo de uma funo mais facilmente reaproveitado do que o cdigo de um programa. Uma boa idia ento transformar o programa da Figura 304 em uma funo, o que resulta no cdigo mostrado na Figura 296. function nComb = Combinacoes(n,k) nComb = fatorial(n) / (fatorial(n-k) * fatorial(k)) endfunction
Figura 296: Uma funo para o clculo do nmero de combinaes de n k a k

8 - Funes

187

Um programa equivalente ao da Figura 304 est mostrado na Figura 297. Voc deve reparar no encadeamento de chamadas: o programa principal chama a funo Combinacoes, que por sua vez contm trs chamadas para a funo fatorial. exec("Combinacoes.sci") exec("fatorial.sci") n=input("n="); k=input("k="); printf("nComb(%d,%d) = %d",n,k,Combinacoes(n,k))
Figura 297: Um programa principal que usa a funo Combinacoes

A Figura 298 ilustra o encadeamento das chamadas neste programa.


Programa Principal

Funo nComb Funo Fatorial


Figura 298: Encadeamento de chamadas

8.2 Forma e Funcionamento


function fat = fatorial(n) fat = 1; for i = 1:n fat = fat*i; end endfunction
Figura 299: Palavras-chave na definio de uma funo

Funes so definidas com o uso das palavras-chave function e endfunction, que delimitam o cdigo da funo.

function fat = fatorial(n) fat = 1; for i = 1:n fat = fat*i; end Parmetro de endfunction
Parmetro de Sada calculado pela funo Entrada fornecido na chamada da funo

Figura 300: Parmetros formais de entrada e de sada da funo

A funo fatorial possui um parmetro formal de entrada, n, e um parmetro formal de sada, fat. Parmetros formais so definidos no cabealho da funo, onde so utilizados como variveis normais. Entretanto, parmetros formais s ganham existncia durante a

8 - Funes

188

execuo da funo; valores assumidos por parmetros formais em execues anteriores no tm qualquer significado. Por contraste, os parmetros usados em chamadas de uma funo so chamados de parmetros reais; so expresses que produzem valores. No incio da execuo da funo cada parmetro formal recebe o valor do parmetro real correspondente; a correspondncia estabelecida pela ordem dos parmetros. A execuo da funo deve calcular um valor para o parmetro formal de sada; este valor utilizado na expresso que contm a chamada da funo. Uma funo pode ter mais de um parmetro formal de sada; a Figura 301 mostra um exemplo de definio e de chamada de uma funo com dois parmetros formais de sada.

function [r1, r2] = eq2g(a,b,c) delta = b^2 - 4*a*c r1 = (-b + sqrt(delta))/(2*a) r2 = (-b - sqrt(delta))/(2*a) endfunction Uma funo pode ter mais de um parmetro de sada Chamada da funo eq2g [raiz1,raiz2] = eq2g(x,y,z)
Figura 301: Funo com dois parmetros formais de sada

Uma funo cria um espao novo para variveis, que podem ter nomes iguais aos de variveis j definidas no programa principal. Variveis criadas pela execuo do corpo de uma funo so chamadas variveis locais. Na funo da Figura 295 a varivel i uma varivel local; o programador desta funo no precisa se preocupar com qualquer outra varivel de mesmo nome definida no programa principal ou em outra funo. Essa delimitao de escopo de variveis uma propriedade essencial para permitir o desenvolvimento de funes por programadores independentes; se no existisse, todos os programadores participantes de um projeto de maior vulto teriam que se preocupar em escolher nomes de variveis que no fossem utilizados por seus colegas. Parmetros de entrada de uma funo podem ser valores numricos, strings, valores lgicos, matrizes de qualquer tipo, e at mesmo uma outra funo. A Figura 302 mostra um exemplo de uma funo que recebe uma funo f como parmetro e que faz o seu grfico para um vetor x.

8 - Funes function PlotaPontos(f,x) y = f(x); plot2d(x,y,style=-1); endfunction function y = MinhaFunc(x) y = exp(- x .^ 2); endfunction // Testador PlotaPontos exec("PlotaPontos.sci"); exec("MinhaFunc.sci"); x = 0:0.1:2*%pi; PlotaPontos(sin,x); PlotaPontos(MinhaFunc,x);
Figura 302: Uma funo que faz o grfico de outra funo recebida como parmetro

189

8.3 Funes, arquivos fonte e o Scilab


Uma funo normalmente escrita em um arquivo com o mesmo nome da funo, e com a extenso .sci, distinta dos arquivos com programas principais Scilab, que tm a extenso .sce.

Figura 303: Um arquivo com uma funo aberto no SciNotes

A Figura 303 mostra um arquivo com a funo fatorial aberto no SciNotes, onde voc pode reparar que o arquivo e a funo tm o mesmo nome, sendo que o arquivo tem a extenso .sci. A mera presena em seu computador de um arquivo com uma funo no basta para que o Scilab saiba de sua existncia. necessrio incorporar a funo ao Scilab, o que pode ser feito com o comando exec(<nome do arquivo com a funo>) que deve ser colocado no programa principal. Um exemplo de uso do comando exec est mostrado na Figura 304.

8 - Funes exec("fatorial.sci") n=input("n="); k=input("k="); nComb = fatorial(n) / (fatorial(n-k) * fatorial(k))


Figura 304: Programa principal para o clculo de combinaes com o comando exec

190

Ateno: o arquivo com a funo deve estar no mesmo diretrio em que se encontra o programa principal, e este deve ser o diretrio corrente do Scilab (veja a Seo Erro! Fonte de referncia no encontrada.).

8.4 Funes e Encapsulamento de Detalhes (e mais sobre arquivos)


Funes servem tambm para isolar detalhes de uma aplicao em uma parte bem definida de um programa. Vamos ilustrar isso mostrando mais possibilidades de tratamento de arquivos no Scilab, conhecimento que em si tambm bastante til. Ns j vimos na Seo 7.11 como ler e escrever todas as linhas de um arquivo com os comandos mgetl e mputl, e na Seo 7.12 como ler e escrever arquivos para e de matrizes numricas, com os comandos fscanfMat e fprintfMat. Isso no o suficiente para o tratamento de arquivos com formatos de uso muito frequente como os que veremos aqui: arquivos com campos em colunas pr-fixadas, e arquivos com campos separados por vrgulas ou por outros caracteres. Para isso vamos precisar de outros comandos, de uso um pouco mais complicado mas que permitem tratar arquivos de forma mais flexvel. O comando d_arq = mopen(nomeArq,"r") abre um arquivo para leitura; se o segundo parmetro de mopen for "w", o arquivo ser aberto para escrita. Aqui a varivel nomeArq deve conter um string com o nome completo de um arquivo, provavelmente obtido com uigetfile. A varivel d_arq recebe como valor um descritor de arquivo, que deve ser usado em todas as operaes de leitura ou de escrita no arquivo, e tambm para o seu fechamento. O comando mclose(d_arq) fecha um arquivo. Operaes de leitura ou de escrita em arquivos devem ser feitas com arquivos abertos, e um programa correto fecha todos os arquivos que abriu (a forma mclose("all") pode ser til para isso). Tipicamente o tratamento de arquivos feito como mostrado na Figura 305. d = mopen(arquivo); // operaes de leitura ou de escrita mclose(d);
Figura 305: Uso tpico de abertura e fechamento de arquivos

Abertura e fechamento de arquivos so operaes necessrias pelo seguinte motivo. Quando no est em uso, um arquivo tem toda a sua informao gravada em disco ou em outra mdia no voltil. Para utilizar um arquivo, o sistema operacional deve trazer para a memria principal informaes sobre o arquivo, como seu tamanho, as posies que fisicamente ocupa no disco (ou em outra mdia), e vrias outras. Isso corresponde abertura do arquivo. Nem todas as alteraes sobre a informao do arquivo mantida na memria so imediatamente refletidas no disco; o fechamento do arquivo garante essa atualizao.

Figura 306: Primeiras linhas de um arquivo com formato de colunas fixas

8 - Funes

191

A Figura 306 mostra um exemplo tpico de arquivo com formato de colunas fixas, descrito na Figura 307.

Colunas Inicial Final 1 4 5 12 13 13 14 50

Contedo Ano de registro Nmero de cadastro em branco Nome

Figura 307: Descrio do arquivo da Figura 306

A Figura 308 mostra uma funo para ler um arquivo com este formato, colocando seu contedo em vetores Ano, Inscr e Nome. function [Ano,Inscr,Nome] = LeAnoInscrNomes(arq) k = 0; d_arq = mopen(arq,"r"); while ~meof(d_arq) linha = mgetl(d_arq,1); k = k + 1; Ano(k) = eval(part(linha,1:4)); Inscr(k) = part(linha,5:12); Nome(k) = stripblanks(part(linha,14:50)); end mclose(d_arq); endfunction
Figura 308: Funo para leitura do arquivo da Figura 306

Temos aqui diversas observaes e novidades: a varivel k usada como um contador de linhas; tem inicialmente o valor 0, e incrementada a cada linha lida. a funo meof(<descritor de arquivo>) retorna um booleano que indica se o fim do arquivo j foi alcanado (eof vem de end of file; o m inexplicvel); a funo mgetl ns j conhecemos, mas aqui temos uma nova forma de uso. No comando linha = mgetl(d_arq,1) uma linha do arquivo de descritor d_arq atribuda varivel linha (o comando linha = mgetl(d_arq, 3) colocaria em linha 3 linhas do arquivo); para extrair as informaes contidas em cada linha, a funo part de extrema valia, pois com ela podemos obter strings que correspondem a uma parte de um outro string; a funo eval utilizada para obter o valor numrico de um string com algarismos, pontos e sinais decimais; a funo stripblanks serve para retirar brancos das extremidades de um string: -->length(" abc ") ans = 11. -->length(stripblanks(" ans = 3. abc "))

8 - Funes

192

A Figura 309 mostra uma funo que faz a operao inversa, isto , grava um arquivo com o formato da Figura 306 a partir de dados presentes em trs vetores. function GravaAnoInscrNomes(Ano,Inscricoes,Nomes,arq) n = size(Ano,"*"); d_arq = mopen(arq,"w"); for i = 1:n mfprintf(d_arq,"%4d%8s%40s\n", ... Ano(i),Inscricoes(i),Nomes(i)) end mclose(d_arq); endfunction
Figura 309: Funo para gravar um arquivo em formato de colunas fixas

Aqui ns utilizamos a funo mfprintf, que a verso de printf para gravar em um arquivos, usando seu descritor.

Figura 310: Primeiras linhas de um arquivo em formato CSV

Na Figura 310 ns vemos as mesmas informaes do arquivo da Figura 310 em um outro formato muito utilizado, onde os campos encontram-se separados pelo caractere ;. Este formato conhecido como formato CSV, de Comma Separated Values, mesmo quando o separador no uma vrgula. function[Ano,Inscr,Nome] = LeAnoInscrNomesCSV(arq) d_arq = mopen(arq,"r"); k = 0; while ~meof(d_arq) linha = mgetl(d_arq,1); k = k + 1; tks = tokens(linha,[";"]); Ano(k) = eval(tks(1)); Inscr(k) = tks(2); Nome(k) = stripblanks(tks(3)); end mclose(d_arq); endfunction
Figura 311: Funo para leitura de um arquivo com o formato CSV da Figura 310

A Figura 311 mostra uma funo que l um arquivo com o formato da Figura 311. Aqui tambm o arquivo lido linha por linha, com a funo tokens sendo utilizada para obter os campos de uma linha como elementos de um vetor de strings.

8 - Funes function GravaAnoInscrNomesCSV(Ano,Inscricoes,Nomes,arq) n = size(Ano,"*"); d_arq = mopen(arq,"w"); for i = 1:n mfprintf(d_arq,"%4d;%8s; %-40s\n",... Ano(i),Inscricoes(i),Nomes(i)) end mclose(d_arq); endfunction
Figura 312: Funo para gravao de um arquivo em formato CSV

193

A gravao de um arquivo com o formato CSV pode ser feita facilmente com o comando mfprintf, como mostra a Figura 312.

8.5 Funes e Desenvolvimento Top-down


Uma tcnica comum de programao a utilizao da chamada de uma funo antes do desenvolvimento da prpria funo, tcnica conhecida como desenvolvimento top-down. Em alguns momentos do desenvolvimento, o programador capaz de especificar o que ele quer que a funo faa, deixando para depois o trabalho de determinar como faz-lo. Vamos aqui ilustrar o emprego de desenvolvimento top-down para construir um programa que: Leia uma srie de nmeros inteiros maiores ou iguais a 2 Para cada nmero lido, encontre o menor nmero primo que seja maior ou igual a ele. Por exemplo, se o nmero lido for 4, o programa deve encontrar o nmero primo 5; se for 11, o programa deve encontrar 11, que j primo. Da matemtica ns sabemos que o conjunto de nmeros primos infinito, ou seja, que sempre existe um nmero primo maior ou igual a um nmero dado. O programa deve terminar quando o usurio entrar com um nmero menor que 2.

Construir um programa que leia uma srie de dados, faa alguma coisa com eles, e termine conforme o desejo do usurio, uma idia que j foi explorada por diversas vezes neste curso. Encontrar o menor primo maior ou igual a um nmero lido nos parece complicado, mas vamos dar incio ao desenvolvimento do programa deixando isso para depois. Veja uma proposta na Figura 313. n = input("n = (use n < 2 se quiser parar):"); while n >= 2 // Encontra o menor primo >= n // e imprime o resultado printf("O menor primo >= %d %d",... n,MenorPrimoMaiorOuIgualA(n)) // L n n = input("n = (use n < 2 se quiser parar):"); end
Figura 313: Programa principal para Menor Primo >= n

Podemos ver que o programa principal cuida da interao com o usurio, empurrando o problema de se encontrar o menor primo para uma funo MenorPrimoMaiorOuIgualA, que ainda no existe. No existe, mas j demos a ela um nome significativo, e especificamos que: A funo tem um nico parmetro de entrada, que o nmero digitado pelo usurio A funo deve retornar o nmero primo que desejamos.

8 - Funes

194

Ou seja, j definimos o cabealho da funo MenorPrimoMaiorOuIgualA. Muito bem, vamos agora encarar o seu desenvolvimento. O algoritmo simples: vamos testar sequencialmente os inteiros a partir do nmero lido, parando ao encontrar um nmero primo. Sim, mas como vamos saber se um inteiro primo? No vamos nos preocupar com isso agora. Outra vez, vamos especificar uma funo e adiar o problema. Veja a Figura 314. function p = MenorPrimoMaiorOuIgualA(n) p = n; while ~Primo(p) p = p+1 end endfunction
Figura 314: A funo MenorPrimoMaiorOuIgualA

Como funciona a funo Primo, no sabemos ainda, mas especificamos que: a funo tem um parmetro formal de entrada, n, que o nmero que queremos testar se ou no primo; o resultado do teste o parmetro formal de sada, que deve ser %t se o nmero for primo, e %f seno.

Para saber se um nmero primo vamos decomp-lo como um produto de fatores inteiros satisfazendo = . Um nmero inteiro maior ou igual a 2 primo se seus nicos fatores so 1 e o prprio . A funo Primo pode ento ser escrita como mostrado na Figura 315, function ehPrimo = Primo(n) ehPrimo = (n == MenorFator(n)); endfunction
Figura 315: A funo Primo

Precisamos agora desenvolver a funo MenorFator. O algoritmo que vamos utilizar bastante direto: vamos usar um inteiro p, com valor inicial 2, e que iremos a cada passo de um loop incrementar e testar se ele um divisor. Para este teste vamos usar a funo Scilab modulo(n,p) , que calcula o resto da diviso de n por p. O loop para ao encontrar o primeiro divisor, o que sempre acontece pois n divisvel por n. Ao trmino do loop, p contm o menor divisor de n. function p = MenorFator(n) p = 2; while modulo(n,p) <> 0 p = p + 1; end endfunction
Figura 316: A funo MenorFator

Com isso ns terminamos o desenvolvimento do nosso programa. importante que voc observe os ganhos obtidos com esse enfoque: Ao desenvolver o programa principal, ns nos preocupamos com a interao com o usurio e, exceto pela definio de funcionalidade, pudemos esquecer do problema de encontrar o nmero primo que desejamos;

8 - Funes

195

Ao desenvolver a funo MenorPrimoMaiorOuIgualA, ns esquecemos da interao com o usurio e nos preocupamos somente com a procura seqencial por um primo a partir de um nmero dado; saber se um nmero primo tambm um problema deixado para outro momento; Ao desenvolver a funo Primo, nosso foco simplesmente descobrir um algoritmo para saber se um nmero inteiro primo ou no; todo o contexto restante pode ser esquecido. Para isso o parmetro de entrada n comparado com o seu menor fator, e a descoberta deste menor fator deixada para depois; Ao desenvolver a funo MenorFator, a nica preocupao encontrar o menor divisor de um nmero inteiro.

esta diviso de tarefas que permite o domnio de programas mais complexos. O desenvolvimento de cada funo pode ser feito por um desenvolvedor em momentos diferentes, ou por pessoas distintas em uma mesma equipe.

8.6 Funes Recursivas


Vamos agora examinar o uso de funes para a prescrio de comportamentos repetitivos. Ns vimos que uma funo pode chamar outra funo, que pode tambm chamar outra funo, que pode ainda chamar outra funo, em um encadeamento de chamadas de profundidade arbitrria. Uma funo pode tambm chamar a si prpria, o que a torna uma funo recursiva. Ns veremos ao longo desse curso que uma formulao recursiva muitas vezes a forma mais natural para a descrio de algoritmos. Como um primeiro exemplo, vamos mostrar uma funo recursiva para o clculo do fatorial de um nmero. Ns sabemos que 1! = 1 e que, para > 1, ! = . ( 1)! A funo fatorialR na Figura 317 calcula o fatorial de um nmero usando de forma muito natural essas equaes. function fat = fatorialR(n) if n > 0 then fat = n*fatorialR(n-1) else fat = 1 end endfunction
Figura 317: Funo recursiva para o clculo do fatorial

Para compreender melhor o funcionamento da execuo de uma funo recursiva, considere o programa FatorialR_Teste da Figura 318.

8 - Funes // Teste de FatorialR exec("FatorialR.sci"); n = input("n = "); while n > 0 do printf("\n%d! = %d",n,FatorialR(n)); n = input("n = "); end
Figura 318: Programa TestaFatorialR.sce

196

Considere tambm a verso de fatorialR da Figura 319, onde tambm colocamos comandos printf envolvendo a chamada (recursiva) da funo. function fat = FatorialR(n) // Comente os printf para no imprimir printf("\nIniciando FatorialR(%d)",n); if n > 1 then fat = n * FatorialR(n-1); else fat = 1; end printf("\nRetornando Fatorial(%d) = %d",n,fat) endfunction
Figura 319: A funo fatorialR, instrumentada para acompanhamento de sua execuo

A execuo deste programa pode gerar a sada mostrada na Figura 320, onde acrescentamos chaves para indicar a correspondncia entre chamadas e retornos da funo.

n = 5

Iniciando FatorialR(5) Iniciando FatorialR(4) Iniciando FatorialR(3) Iniciando FatorialR(2) Iniciando FatorialR(1) Retornando Fatorial(1) Retornando Fatorial(2) Retornando Fatorial(3) Retornando Fatorial(4) Retornando Fatorial(5) 5! = 120

= = = = =

1 2 6 24 120

Figura 320: Sada do programa TestaFatorialR.sce

Chamadas e retornos de funes seguem um mecanismo clssico em computao, chamado de pilha. Em uma pilha de livros normalmente coloca-se um novo livro encima da pilha, e retira-se o livro no topo da pilha.
Fat(1) Fat(2) Fat(3) Fat(4) Fat(5) Prog Prog Fat(5) Prog Fat(4) Fat(5) Prog Fat(3) Fat(4) Fat(5) Prog Fat(2) Fat(3) Fat(4) Fat(5) Prog

Fat(2) Fat(3) Fat(4) Fat(3) Fat(4) Fat(4)

Fat(5)
Prog

Fat(5)
Prog

Fat(5)
Prog

Fat(5)
Prog Prog

Figura 321: Pilha de execuo de FatorialR

8 - Funes

197

A Figura 321 ilustra a evoluo da pilha de execuo do programa TestaFatorialR.sce quando executado com n == 5. No incio somente o programa principal est em execuo. A primeira chamada de FatorialR feita com o parmetro real 5. Temos neste momento o programa principal e uma instncia da funo em execuo. Mas o clculo do fatorial de 5 exige outra chamada de FatorialR, desta vez com o parmetro real 4, o que nos leva a ter em execuo o programa principal e duas instncias de FatorialR. Para o clculo do fatorial de 4, precisamos do fatorial de 3, e assim vamos at chegarmos a uma pilha com o programa principal e cinco instncias de FatorialR, que na ltima vez ter sido chamada com o parmetro real 1. Com o parmetro real igual a 1 FatorialR retorna sem outra chamada recursiva, o que reduz a quatro o nmero de instncias em execuo. Isso marca o incio de uma sequncia de retornos e de desempilhamentos, at termos novamente somente o programa principal em execuo. A recursividade portanto uma outra forma de se prescrever um comportamento repetitivo para um programa. possvel por exemplo formular o algoritmo de descoberta do menor valor presente em um vetor como uma funo recursiva. Uma possibilidade usa a seguinte relao de recorrncia: se length(A) == 1, o menor valor presente em A A(1) se length(A) > 1, o menor valor presente em A o menor entre A(1) e o menor valor presente em A(2:length(A))

o que nos leva a uma formulao recursiva do mesmo algoritmo que usamos na funo Minimo. Outra relao de recorrncia que pode ser usada : se length(A) == 1, o menor valor presente em A A(1) se length(A) > 1, o menor valor presente em A o menor dentre (o menor valor presente na metade esquerda de A) e (o menor valor presente na metade direita de A)

A partir desta segunda relao de recorrncia ns podemos derivar a funo recursiva da Figura 322. function m = MinimoR(x) if length(x) == 1 then m = x(1) else half = int(length(x)/2); minLeft = MinimoR(x(1:half)); minRight = MinimoR(x(half+1:length(x))); if minLeft <= minRight then m = minLeft else m = minRight end end endfunction
Figura 322: Funo MinimoR, recursiva

9 Algoritmos, Pesquisa

198

9 Algoritmos, Pesquisa
9.1 Definio e Caractersticas
Um problema de transformao de informao descreve uma entrada de informao e propriedades requeridas de uma informao de sada. Um algoritmo resolve um problema de transformao de informao, sendo constitudo por uma prescrio de passos que transformam uma informao de entrada em outra informao de sada. Cada passo prescrito deve ser uma operao garantidamente realizvel, seja por operaes elementares, seja por outro algoritmo. Um programa a concretizao de um algoritmo em uma linguagem executvel. Ns lidamos com algoritmos desde o incio deste texto, mas agora vamos dar um tratamento mais formal a este conceito. Trs questes so bsicas para a caracterizao de problemas de transformao de informao e algoritmos: Especificao: qual exatamente o problema de transformao de informao que queremos resolver? Correo: um dado algoritmo resolve mesmo o problema proposto em sua especificao? Eficincia: com qual consumo de recursos computacionais (essencialmente, tempo e memria) o algoritmo executa a sua funo?

Ns iremos a seguir detalhar um pouco mais cada uma dessas questes. Especificaes surgem de um processo de anlise de uma necessidade de transformao de informao. Uma especificao no esttica; muitas vezes uma especificao modificada durante e mesmo aps o processo de desenvolvimento de um programa. Uma condio no prevista muitas vezes a causa de uma alterao em uma especificao. Como um exemplo, no programa que vimos para a soluo de muitas equaes de 2 grau com coeficientes em um arquivo (Erro! Fonte de referncia no encontrada.), ns no demos um tratamento especial para o caso de termos o primeiro coeficiente nulo, o que provoca uma diviso por zero no clculo das raizes. Se em uma linha do arquivo de coeficientes tivermos = 0, a diviso por zero provocar uma interrupo da execuo do programa, sem o processamento das equaes restantes. Se isso no for um comportamento aceitvel, necessrio modificar a especificao para dar um tratamento adequado a esta situao, que poderia ser, por exemplo, ignorar a linha com = 0, ou seno resolver a equao de primeiro grau resultante. Em problemas reais comum que a fase de especificao seja a etapa mais demorada e a mais cara de um projeto de desenvolvimento de um programa. No existe situao pior para uma equipe de desenvolvimento do que, ao dar por terminado um sistema, constatar que ele no atende s necessidades do cliente, necessidades que, por deficincias no processo de anlise, no foram explicitadas na especificao. Apesar dessa importncia, neste curso ns procuraremos lidar com problemas cuja especificao bem simples, pois nosso objetivo aqui a criao de uma cultura algortimica para o aluno. Tcnicas de anlise e de especificao de sistemas so matrias que voc poder depois estudar em cursos mais avanados de programao ou de engenharia de software. possvel verificar se um algoritmo atende a uma especificao por um exame de sua estrutura, com a construo de uma prova formal de sua correo. Na prtica uma prova formal de correo s vivel para algoritmos muito pequenos. O que se faz produzir uma argumentao informal da correo de um algoritmo.

9 Algoritmos, Pesquisa

199

Alm desta argumentao, testes so usados para se ganhar convico do bom funcionamento de um algoritmo concretizado em um programa. entretanto importante ter em mente que testes podem descobrir erros, mas raramente podem garantir a sua ausncia. Este problema vem do fato de que mesmo algoritmos muito simples tm tantas entradas possveis que testes s podem cobrir uma nfima frao dessas possibilidades.

SC

SC

SC

SC

Figura 323: Um somador de 4 bits

Usando um exemplo retirado de (Dijkstra, 1972) vamos considerar uma transformao bsica de informao, feita por um somador em cascata similar ao mostrado na Figura 323, mas com largura de 32 bits. Se algum quiser considerar o somador como uma caixa preta a ser testada, teramos 264 (considerando as duas entradas de 32 bits cada) valores para as entradas a serem testadas, o que claramente inexeqvel. Uma argumentao baseada na estrutura do somador o que nos prov a convico de sua correo. Se estamos convencidos da correo de um circuito de soma completa, como o mostrado na Figura 92 (e estamos, pela forma de desenvolvimento a partir da tabela da verdade), e se compreendemos a lgica do arranjo em cascata, no temos dificuldades para acreditar no bom funcionamento do somador de 32 bits. A compreenso completa da estrutura de um programa grande estamos falando de milhares ou mesmo milhes de linhas de cdigo, produzidas por vrios desenvolvedores por sua vez dificilmente atingvel. No possvel testar completamente um programa grande, e nem possvel compreender completamente sua estrutura. E agora, Jos? Bom, isso mesmo. No existe uma boa sada. A indstria de software investe em qualidade de desenvolvimento, em testes, mas quase sempre vende programas sem garantia. Neste curso ns iremos trabalhar com programas pequenos, todos com menos de 100 linhas. A convico de correo ser fornecida tanto com argumentos estruturais como por testes. Para atender a uma mesma especificao possvel encontrar algoritmos que apresentam enormes diferenas em sua eficincia. O temo complexidade computacional, ou simplesmente complexidade, usado para designar como o uso de recursos computacionais por um algoritmo varia em funo de seus dados de entrada. Complexidade temporal refere-se eficincia em tempo de execuo; complexidade espacial refere-se eficincia no uso de memrias. Na Cincia da Computao, um algoritmo tem complexidade maior que outro quando menos eficiente, e no, como se poderia pensar com o uso habitual da palavra, mais complicado do que o outro. Na verdade, espera-se que algoritmos mais complicados tenham complexidade computacional menor do que a de algoritmos mais simples. Algoritmos com complexidade maior (menos eficientes) e mais complicados no tm nenhuma vantagem de uso, e inevitavelmente caem no esquecimento.

9 Algoritmos, Pesquisa

200

9.2 Fatorao
Para ganharmos algum sentimento de como algoritmos que satisfazem uma mesma especificao podem diferir em eficincia, ns vamos fazer alguns experimentos de medidas de tempo gasto com a fatorao de nmeros inteiros, um problema de importncia fundamental para a rea de segurana da informao. A segurana da criptografia da maior parte dos sistemas atuais depende da dificuldade da fatorao de nmeros semi-primos, isto , nmeros que so formados pelo produto de dois primos. Estamos aqui falando de nmeros grandes: chaves criptogrficas atuais tm costumeiramente 1024 ou 2048 bits, que correspondem a nmeros com 308 ou 616 algarismos decimais. O Scilab oferece a funo timer() que permite medir o tempo gasto na execuo de trechos de um programa. A primeira execuo da funo timer() zera e dispara um cronmetro; cada chamada subseqente da funo timer() retorna o valor em segundos do tempo decorrido desde a chamada anterior da funo. // Programa para fatorar nmeros inteiros exec("MenorFator.sci") n = input("n = "); while n >= 2 timer(); p = MenorFator(n) ; tempoGasto = timer(); // Imprime o resultado printf("\nTempo = %8.6fs, %6d divisvel por %6d", tempoGasto,n,p); if n == p then printf(" **PRIMO**") end n = input("n = "); end
Figura 324: O programa Fatora.sce

Na Figura 324 ns vemos o programa Fatora.sce, que l nmeros e encontra o menor fator divisor dos nmeros lidos, destacando em sua sada os nmeros primos. A verificao feita pela funo MenorFator, mostrada na Figura 316. Repare como a funo timer() utilizada no programa Fatora.sce para medir o tempo gasto na execuo da funo MenorFator. Nosso primeiro experimento muito simples. Vamos utilizar o programa Fatora.sce para encontrar o menor divisor de 131101, que primo, e tambm de 131103, que no . n = 131101 Tempo = 3.062500s, 131101 divisvel por 131101 **PRIMO** n = 131103 Tempo = 0.000000s, 131103 divisvel por 3

Figura 325: Tempos para fatorar nmeros primos e no primos

Na Figura 325 ns vemos o resultado do experimento. Encontrar o menor fator de um nmero primo tomou mais de 3 segundos, enquanto o tempo tomado para encontrar o menor fator de um nmero divisvel por 3 foi to pequeno que a funo timer retornou zero. Isso nos leva importante observao de que o tempo gasto pode variar muito com a instncia de um problema. fcil entender o que aconteceu olhando o cdigo da funo MenorFator. Nmeros primos so o pior caso para a funo MenorFator. Na primeira chamada, foram feitas 131103 execues da funo modulo, e, na segunda, apenas 3. Com isso, uma primeira

9 Algoritmos, Pesquisa

201

observao: algoritmos podem ter seu tempo de execuo dependente da instncia especfica do problema que resolve. Muitas vezes ns estamos interessados na anlise do pior caso de um algoritmo. Ns iremos em seguida relatar outros experimentos feitos com o programa Fatora.sce. Nestes experimentos ns vamos precisar de nmeros primos, e para isso o arquivo 200000primos.txt, que contm os 200.000 primeiros nmeros primos, de grande utilidade. Diversos sites na Internet, como 48, contm arquivos com nmeros primos ou programas que geram nmeros primos. A Figura 326 mostra as primeiras e ltimas linhas deste arquivo.

Figura 326: Primeiros e ltimos nmeros primos no arquivo 200000primos.txt

No segundo experimento, fizemos o programa Fatora.sce fatorar por diversas vezes se o nmero 131101, que primo. Veja os resultados na Figura 327. n = 131101 Tempo = 2.984375s, 131101 divisvel por 131101 **PRIMO** n = 131101 Tempo = 3.078125s, 131101 divisvel por 131101 **PRIMO** n = 131101 Tempo = 3.015625s, 131101 divisvel por 131101 **PRIMO**
Figura 327: Variaes no tempo de execuo de um programa com os mesmos dados de entrada

Voc pode ver que um mesmo programa apresenta variaes no tempo gasto para a fatorao do mesmo nmero primo. Isso se deve a uma srie de fatores, o principal deles sendo o fato de que, em um sistema operacional como o Windows ou o Linux, um programa no executa sozinho, mas compartilha o processador e outros recursos do computador com outros programas e com o prprio sistema operacional. Esse compartilhamento coordenado pelo sistema operacional, e o programador Scilab no tem qualquer controle sobre a forma como se d este compartilhamento. A funo timer procura calcular o tempo efetivo de processamento de um programa, mas com imprecises que voc j pde apreciar. por isso que uma mesma funo, chamada com os mesmos parmetros, pode apresentar diferenas de desempenho a cada execuo.

48

The Prime Pages (prime number research, records and resources), acessado 7 de maro de 2011, http://primes.utm.edu/index.html.

9 Algoritmos, Pesquisa
Tabela 4: Tempos (segundos) gastos com a funo MenorFator em um notebook e em um desktop

202

Primo Notebook 257 0,01560 521 0,04680 1031 0,03120 2053 0,10920 4099 0,17160 8209 0,39000 16411 0,68640 32771 14,19609 65537 29,17219 131101 58,03237 262147 11,94968 524309 23,50935 1048583 47,04990 2097169 93,05460

Desktop 0,03125 0,01563 0,04688 0,01563 0,06250 0,21875 0,29688 0,76563 1,53125 2,93750 6,29688 11,21875 24,54688 49,60938

Outro experimento procura capturar o impacto do valor do nmero primo recebido como parmetro sobre o tempo de execuo da funo MenorFator. A Tabela 4 mostra os resultados obtidos com diversos nmeros primos, em experimentos realizados com dois computadores com velocidades distintas. O grfico da Figura 328 resulta desta tabela, e ele torna clara a relao de linearidade entre o valor do nmero primo e o tempo consumido pela funo MenorFator.

Figura 328: Tempo para fatorao em funo do valor de nmeros primos em dois computadores

9 Algoritmos, Pesquisa

203

A Cincia da Computao se preocupa exatamente em determinar a complexidade de um algoritmo por uma anlise do algoritmo em si; experimentos naturalmente ajudam a formar uma intuio. Um exame da funo MenorFator (Figura 316) nos teria permitido prever seu comportamento. Quando o nmero testado primo, a funo modulo aplicada a todos os inteiros menores ou iguais a ele. Como a se encontra todo o esforo computacional, poderamos j ter previsto um crescimento linear do tempo de execuo em funo do valor do nmero primo examinado. A constante de linearidade em si depende do computador onde a funo MenorFator executada. Para o notebook, o tempo gasto com um nmero primo aproximadamente igual a 4,49 105 segundos; para o desktop, 2,31 105 segundos, ou seja, o desktop aproximadamente duas vezes mais rpido do que o notebook (no tome isso como uma afirmativa genrica; estamos falando do desktop e do notebook empregados nos experimentos). Para poder comparar algoritmos, procura-se determinar a complexidade temporal de um algoritmo de forma independente da velocidade de um computador especfico e de outros fatores que afetam o tempo de execuo de um programa. Um algoritmo tem a sua complexidade conhecida quando conseguimos encontrar uma funo que descreva a ordem de crescimento de seu tempo de execuo com relao ao tamanho de sua entrada. E qual o tamanho da entrada da funo MenorFator? Seu nico parmetro de entrada um nmero, que, para fins de anlise do algoritmo, podemos supor ser representado como binrio sem sinal com bits. Ns vimos que, para o pior caso da execuo de MenorFator , o tempo cresce linearmente com o valor do primo fatorado, que prximo de 2 , onde o nmero de bits necessrios para a representao do primo.

Figura 329: Tempos para fatorao em funo do nmero de bits de um nmero primo em dois computadores

Se o tamanho da entrada de um problema, ns dizemos que uma funo () caracteriza a complexidade de um algoritmo quando seu tempo de execuo limitado por () multiplicado por uma constante. Ns dizemos que sua complexidade da ordem de (), o que escrito () = (()) (pronuncia-se de ()). No caso do algoritmo utilizado pela funo MenorFator, temos () = (2 ), e por isso dizemos que o algoritmo tem

9 Algoritmos, Pesquisa complexidade exponencial. A idia aqui ter informao til sobre o desempenho de um algoritmo, que no dependa da velocidade de computadores especficos. A constante de multiplicao serve para isso: ela absorve pequenas perturbaes na execuo, e pode incorporar diferenas de desempenho dos computadores.

204

Vamos agora considerar a funo MenorFator2, mostrada na Figura 330, que implementa um algoritmo melhor para a fatorao de um nmero. Este novo algoritmo se baseia na observao de que, se um divisor de um inteiro positivo , porque existe tal que = . Se = , = e um quadrado perfeito; se , ou bem < ou bem < . Isto significa que s precisamos testar a divisibilidade para os inteiros menores ou iguais raiz quadrada de ; se neste intervalo no encontrarmos nenhum divisor, j poderemos concluir que primo. function p = MenorFator2(n) limite = int(sqrt(n)); p = 2; while modulo(n,p) <> 0 & p <= limite p = p + 1; end if modulo(n,p) <> 0 then p = n; end endfunction
Figura 330: A funo MenorFator2

Uma anlise direta da funo MenorFator2 mostra que so realizadas chamadas da funo mdulo em nmero igual raiz quadrada do valor do nmero primo sendo fatorado. Portanto, sua complexidade () = (2 ) = (22 ). Experimentamos a funo MenorFator2 para verificar fatorar 2750159, o maior primo presente no arquivo 2000000primos.txt, e o tempo gasto no desktop foi de 0,047 segundos, enquanto que a funo MenorFator gastou 88,360 segundos, uma diferena enorme de desempenho. Quando = 10, a funo modulo chamada aproximadamente 1024 vezes pela MenorFator, e somente 32 vezes pela MenorFator2. Quando = 20, a funo modulo chamada aproximadamente 220 = 1.048.576 vezes pela MenorFator, e 1024 vezes pela MenorFator2. Ao passar o nmero de bits da entrada de 10 para 20, a MenorFator demora 1024 vezes mais, enquanto a MenorFator2 demora 32 vezes mais.

9 Algoritmos, Pesquisa
Tamanho da Instncia do Problema 10 20 30 40 50 60

205

Funo de complexidade

n n2 n3 n5 2n 3n

0,00001 0,00002 0,00003 0,00004 0,00005 0,00006 segundos segundos segundos segundos segundos segundos 0,0001 0,0004 0,0009 0,0016 0,0025 0,0036 segundos segundos segundos segundos segundos segundos 0,001 0,008 0,027 0,064 0,125 0,216 segundos segundos segundos segundos segundos segundos 0,1 3,2 24,3 1,7 5,2 13,0 segundos segundos segundos minutos minutos minutos 0,001 1,0 17,9 segundos segundos segundos 0,059 58 segundos minutos 6,5 anos 12,7 dias 3855 sculos 35,7 anos 366 sculos

2 108 1,3 1013 sculos sculos

Figura 331: Quadro comparativo de funes de complexidade

A Figura 331, extrada do livro de Garey e Johnson49, nos ajuda a formar uma idia do que esperar do desempenho de algoritmos com funes de complexidade exponencial quando aplicados a problemas grandes.

Maior instncia que um computador resolve em 1 hora Computador Computador Funo de Computador 100x mais 1000x mais complexidade Atual rpido rpido N 100 N 1000 N n

n2 n3 n5 2n 3n

M Z W X Y

10 M 4,64 Z 2,5 W X + 6,64 Y + 4,19

31,6 M 10 Z 3,98 W X + 9,97 Y + 6,29

Figura 332: Efeito do aumento da velocidade de computadores sobre o tamanho dos problemas resolvveis

Computadores de um mesmo preo dobram de velocidade em menos de dois anos, mas algoritmos com funes de complexidade exponencial so relativamente pouco afetados. O efeito de termos computadores 100 ou 1000 vezes mais rpidos que os atuais sobre algoritmos com funes de complexidade exponencial est mostrado na Figura 332, que tambm foi retirada da referncia50. Ali vemos que se hoje um computador resolve em uma hora um problema de tamanho, digamos, 200, usando um algoritmo (2 ), com um computador 1000 vezes mais rpido conseguiremos resolver um problema de tamanho ~210.

49

M. R. Garey e D. S. Johnson, Computers and Intractability: A Guide to the Theory of NP-Completeness, First Edition (W. H. Freeman, [s.d.]). 50 Ibidem.

9 Algoritmos, Pesquisa

206

9.3 Pesquisa
Vamos agora estudar um problema clssico da Cincia da Computao, que a pesquisa para verificar se um elemento procurado existe em uma tabela. Extenses deste problema fazem parte do nosso dia a dia, em mquinas de busca como Google e Yahoo, ou na localizao de uma palavra em um arquivo. Vamos examinar aqui dois algoritmos: a pesquisa seqencial e a pesquisa binria. Como um exemplo ns vamos utilizar algoritmos de pesquisa para testar a primalidade de um nmero, a tabela sendo composta pelos nmeros primos presentes no arquivo 200000primos.txt. Obviamente isto s funciona para nmeros menores ou iguais ao maior nmero presente no arquivo, 2750159. A especificao do problema que iremos resolver de duas maneiras distintas : Faa um programa que: Leia o arquivo 200000primos.txt, que contm os primeiros 200000 nmeros primos; Leia repetidamente nmeros inteiros e, para cada nmero lido, verifique se o nmero primo pesquisando por ele na tabela; O programa deve parar quando o nmero lido for 0 (zero).

9.4 Pesquisa Seqencial


A Figura 333 mostra o programa VerificaPrimos3.sci, onde podemos notar que: Os primeiros comandos fazem a leitura da tabela de nmeros primos; O programa apresenta a nossa velha conhecida estrutura de repetio controlada pelo usurio; A verificao efetiva da primalidade foi deixada para a funo Primo3, que tem como parmetros de entrada o nmero digitado pelo usurio e a tabela lida do arquivo.

// Programa para deteo de nmeros primos exec("Primo3.sci") exec("seqSearch.sci") arqTab = uigetfile("*.txt",pwd(),"Arquivo com Tabela"); tabPrimos = fscanfMat(arqTab); n = input("n = "); while n >= 2 timer(); eh_Primo = Primo3(n,tabPrimos); tempoGasto = timer(); // Imprime o resultado printf("\nTempo gasto = %g segundos", tempoGasto); if eh_Primo then printf("\nO nmero %d primo!\n\n",n); else printf("\nO nmero %d no primo!\n\n", n) end n = input("n = "); end
Figura 333:O programa VerificaPrimos3.sci, que utiliza pesquisa seqencial

A funo Primo3 apenas um envelope sobre uma funo de pesquisa seqencial, como mostra a Figura 334.

9 Algoritmos, Pesquisa function ePrimo = Primo3(n,tabela) ePrimo = seqSearch(n,tabela) ~= -1; endfunction


Figura 334: A funo Primo3

207

A funo seqSearch mostrada na Figura 335 implanta uma pesquisa seqencial. Ali podemos observar que: O vetor table examinado sequencialmente a partir de sua primeira posio. O loop de pesquisa pra por um de dois motivos: quando o limite superior da tabela for atingido, ou quando a chave for encontrada. Aps a sada do loop feito um teste para se saber por qual motivo o loop while terminou. Se a chave procurada no consta da tabela, o parmetro de sada p recebe o valor -1, uma conveno til para quem chama a funo, como a funo Primo3. function p = seqSearch(key,table) i = 1; while i <= length(table) & table(i) ~= key i = i+1; end if i <= length(table) then p = i; else p = -1; end endfunction
Figura 335: A funo seqSearch para pesquisa seqencial

Quanto complexidade da pesquisa seqencial, no difcil ver que se o tamanho da tabela, o nmero de comparaes com a chave feito em uma pesquisa por um elemento presente na tabela varia entre 1 e ; pesquisas por elementos que no constam da tabela (o que constitui o pior caso) consomem sempre comparaes com a chave. Se considerarmos todas as chaves presentes na tabela como tendo a mesma probabilidade de serem pesquisadas, o algoritmo far em mdia /2 comparaes por pesquisa por chave constante da tabela. O nmero de comparaes cresce portanto linearmente com o tamanho da tabela, e ns dizemos que o algoritmo de pesquisa seqencial (), ou seja, da ordem de , ou ainda, dizemos que a pesquisa seqencial tem complexidade linear.

9.5 Pesquisa Binria


Quando uma tabela tem suas entradas dispostas em ordem crescente ou decrescente ns podemos usar um algoritmo muito mais eficiente para a pesquisa, e que se assemelha ao mtodo como ns humanos procuramos palavras em um dicionrio. A primeira comparao feita no com o primeiro elemento da tabela, mas com o elemento no meio da tabela. Supondo que os elementos da tabela esto em ordem crescente, se a chave procurada for menor que o elemento no meio da tabela, podemos restringir a pesquisa metade inferior da tabela, pois a parte superior s contm elementos maiores do que a chave procurada. Da mesma forma, se a chave procurada for maior que o elemento no meio da tabela, podemos restringir a pesquisa metade superior da tabela. O mtodo reaplicado parte restante da tabela, e continua at que ou a chave encontrada, ou a parte da tabela em considerao tem tamanho igual a 0, situao em que podemos

9 Algoritmos, Pesquisa

208

concluir que a chave no consta da tabela. A denominao de pesquisa binria vem do fato da diviso do tamanho do problema por 2 a cada passo do algoritmo. function p = BinarySearch(key,table,low,high) if high < low then p = -1; else m = int((low+high)/2); if key == table(m) then p = m; else if key < table(m) then p = BinarySearch(key,table,low,m-1); else p = BinarySearch(key,table,m+1,high); end end end endfunction
Figura 336: A funo recursiva BinarySearch

A Figura 336 mostra uma implementao direta da pesquisa binria como uma funo recursiva. function position = binSearch(key,table) low = 1; high = length(table); while high - low > 1 m = int((high+low)/2); if key >= table(m) then low = m; end if key <= table(m) then high = m; end end if key == table(high) then position = high; else if key == table(low) then position = low; else position = -1; end end endfunction
Figura 337: A funo binSearch

A funo binSearch (Figura 337) uma implementao no recursiva em Scilab do algoritmo de pesquisa binria, onde podemos observar que: a funo utiliza dois ponteiros, low e high, que indicam a cada passo qual parte da tabela que pode conter a chave procurada. A condio low <= high mantida em todas as alteraes de valores dessas variveis.

9 Algoritmos, Pesquisa

209

a cada passagem do loop o elemento comparado com a chave buscada est na posio m = int(high+low)/2 . o ponteiro low tratado de forma a manter sempre a afirmativa se key < table(low), ento key no consta da tabela, que valida inicialmente, e que permanece vlida a cada atualizao de low; o ponteiro high cumpre papel similar, mantendo sempre vlida a afirmativa se key > table(high), ento key no consta da tabela ; quando o loop termina, a parte da tabela que pode conter um elemento igual chave est entre low e high e, pela condio de trmino do loop e pela relao entre low e high,0 <= high low < = 1. os testes que sucedem ao loop permitem decidir se a tabela contm ou no um elemento igual chave procurada.

A anlise da complexidade do pior caso da pesquisa binria simples. A cada passo o tamanho da parte da tabela que pode conter a chave dividido por 2, e o algoritmo termina quando o tamanho desta parte igual a 1. Se a tabela tem elementos, teremos no pior caso, log 2 comparaes, onde indica a funo teto, que mapeia um nmero real no menor inteiro maior ou igual a . No caso da tabela armazenada no arquivo 200000primos.txt, temos no pior caso log 2 200.000 = 17,60964 = 18 comparaes para completar a pesquisa. Compare isso com o pior caso da pesquisa seqencial, que pode necessitar de 200.000 passos para terminar. Pior: se a tabela dobrar de tamanho, passando a ter 400.00 elementos, o algoritmo de pesquisa binria ir passar a necessitar de 19 comparaes, uma a mais, enquanto que o algoritmo de pesquisa seqencial poderia necessitar de 400.000 passos. Por estes argumentos algum poderia pensar que, em casos em que temos uma tabela ordenada, a opo pela pesquisa binria em detrimento da pesquisa seqencial uma escolha bvia, mas nem sempre este o caso. A pesquisa seqencial mais simples, mais fcil de programar, e menos propensa a erros de programao. E muitas vezes trabalhamos com tabelas pequenas, onde a diferena de desempenho entre os dois algoritmos no importante. Ao programar, nunca se esquea do kiss principle, um acrnimo para uma frase em ingls que todos os bons programadores dizem a si prprios todos os dias: keep it simple, stupid. Ou seja, s complique quando inevitvel.

10 - Ordenao

210

10 Ordenao
1 2 3 4 5 6 7

34 56 27 45 12 44 34
1 2 3 4 5 6 7

Vetor no ordenado Vetor ordenado

12 27 34 34 44 45 56

Figura 338: Ordenao de um vetor

Outro problema clssico da Cincia da Computao a ordenao, que consiste em, dado um vetor A, obter outro vetor com os mesmos elementos de A, dispostos em ordem crescente (ou decrescente), como mostra a Figura 338. Uma outra forma de se ver o efeito de uma operao de ordenao est ilustrada na Figura 339.

Figura 339: Grfico dos valores de um conjunto desordenado e aps sua ordenao

Existem muitos algoritmos para ordenao; ns veremos trs deles aqui, conhecidos por algoritmos de ordenao por seleo e troca, por intercalao e por intercalao.

10.1 Seleo e Troca


O primeiro algoritmo que iremos estudar conhecido como o mtodo de Seleo e Troca (em ingls, Select Sort), por motivos que se tornaro bvios. Vamos comear apresentando o cabealho de uma funo que iremos desenvolver para implantar esse algoritmo, mostrado na Figura 340. function sA = SelectSort(A) // Constri o vetor sA com os // mesmos elementos do vetor A // dispostos em ordem crescente. endfunction
Figura 340: Cabealho de uma funo de ordenao

Isso j nos permite desenvolver um programa para testar a funo, mostrado na Figura 341.

10 - Ordenao exec("SelectSort.sci"); a = int(10*rand(1,4)) aa = SelectSort(a) b = int(10*rand(1,6)) bb = SelectSort(b) c = int(10*rand(1,9)) cc = SelectSort(c)


Figura 341: O programa SelectSort_teste.sce

211

O programa SelectSort_teste.sce bastante simples, e nos permite verificar por inspeo visual a correo da funo por testes com pequenos vetores randmicos. Ele gera 3 pequenos vetores randmicos que so passados como parmetros de entrada para a funo. Repare na ausncia dos ; em quase todos os comandos; queremos tirar proveito do eco automtico do Scilab para a impresso dos vetores antes e depois da ordenao. O algoritmo de ordenao por seleo e troca tambm desenvolvido por um raciocnio indutivo: Suponhamos que as k-1 primeiras posies do vetor A j contenham elementos em suas posies finais; Selecionamos o elemento de menor valor entre A(k) e A(length(A)) ; Trocamos o valor deste menor elemento com o valor em A(k). Com isso teremos mais um elemento em sua posio final, e podemos fazer k = k+1.

O algoritmo se inicia com k igual a 1, o que torna vazia a poro do vetor com elementos em suas posies finais. Na Figura 342 ns vemos uma ilustrao deste mtodo: No primeiro passo o menor elemento entre 1 (igual a k) e 7 (comprimento do vetor) tem o valor 12, e se encontra na posio 7. Os valores nas posies 1 e 7 so trocados, e k passa a valer 2. No segundo passo, o menor elemento entre 2 (igual a k) e 7 tem o valor 27, e se encontra na posio 3. Ele trocado com o elemento na posio 2, e k passa a valer 3.

Desta forma o algoritmo progride, e termina quando a penltima posio do vetor recebe o seu valor final o que significa que a ltima posio tambm estar corretamente preenchida.
1 2 3 4 5 6 7

34 56 27 45 12 44 34
1 2 3 4 5 6 7

12 56 27 45 34 44 34
1 2 3 4 5 6 7

12 27 56 45 34 44 34
1 2 3 4 5 6 7

12 27 34 45 56 44 34
1 2 3 4 5 6 7

12 27 34 34 56 44 45
1 2 3 4 5 6 7

12 27 34 34 44 56 45
1 2 3 4 5 6 7

12 27 34 34 44 45 56
Figura 342: Ordenao por Seleo e Troca

10 - Ordenao

212

Figura 343: Seleo de elementos para troca de posio: em azul, o elemento na primeira posio da parte ainda no ordenada e, em vermelho, o menor elemento na parte no ordenada

J temos condies de dar um primeiro refinamento funo SelectSort, que mostramos na Figura 344. function sA = SelectSort(A) for k = 1:length(A)-1 // Seleciona a posio entre A(k) e // A(length(A)) que contm o menor valor // Troca o valor de A(k) com o valor na // posio selecionada. end sA = A; endfunction
Figura 344: Primeiro refinamento da funo OrdenaPorSeleo

Prosseguindo no refinamento, vamos atacar inicialmente o problema da troca de valores entre duas posies do vetor A. Trocar os valores de duas variveis x e y no uma operao bvia. Se fizermos x = y; y = x, o valor antigo de x que queramos armazenar em y perdido. Se fizermos y = x; x = y, teremos o problema inverso. A soluo o uso de uma varivel temporria (adjetivo empregado para variveis cuja utilidade tem um carter destacadamente local e auxiliar) temp, e fazer temp = x; x = y; y = temp, o que nos d a soluo desejada. Muito simples, depois que sabemos. Para a etapa de seleo do menor elemento, ns j desenvolvemos um loop com funo parecida (veja a Figura 254), que encontra o menor valor presente em um vetor. Podemos aproveitar o seu cdigo, adaptando-o aos requisitos que temos agora. Precisamos de uma funo, que vamos chamar de MinimoPos, que: procure o menor valor no em todo o vetor de entrada, mas em parte dele, e informe alm do menor valor, a posio onde foi encontrado.

10 - Ordenao

213

function [m,im] = MinimoPos(A,low,high) // Encontra o menor valor // presente no vetor A entre as // posies low e high, e informa // sua posio no vetor m = A(low); im = low; for k = low+1:high if m > A(k) m = A(k); im = k; end end endfunction
Figura 345: A funo SelecionaMenor

Como voc pode reparar na Figura 345, as modificaes introduzidas memorizam na varivel im a posio onde o mnimo corrente foi encontrado (nas situaes em que m atualizada), restringem o espao da busca apenas aos elementos de A com ndices entre os parmetros de entrada low e high, e acrescentam um parmetro de sada. Se a funo Minimo mereceu a construo de um programa para seu teste, uma boa idia fazer o mesmo para a funo MinimoPos, que um pouco mais complicada. Voc poderia pensar que, indiretamente, o programa OrdenaPorSelecao_teste j o faria, mas construir um testador independente tem a grande vantagem de simplificar o contexto de uso da funo MinimoPos. // Programa que testa a funo MinimoPos exec("MinimoPos.sci"); exec("PrintMatrix.sci"); a = int(100*rand(1,10)); PrintMatrix("A",a); inicio = input("Inicio = "); fim = input("Fim = "); while inicio > 0 [m im] = MinimoPos(a,inicio,fim) printf("Menor valor entre %d e %d = %d, na posio %d",... inicio,fim,m,im); inicio = input("Inicio = "); fim = input("Fim = "); end function PrintMatrix(Label, M); printf("\n%s = [",Label); for i = 1:length(M) printf("%3d",M(i)); end printf("]") endfunction
Figura 346: O programa MinimoPos_teste e a funo PrintMatrix

A Figura 346 mostra o programa MinimoPos_teste.sce, juntamente com uma funo auxiliar PrintMatrix, cuja utilidade simplesmente a impresso de um vetor em um formato mais agradvel do que o padro do Scilab. Este programa gera um vetor com 10

10 - Ordenao

214

elementos aleatrios, e permite que o usurio repetidamente escolha um ponto inicial para a seleo da posio com o menor elemento a partir do ponto inicial. A Figura 347 mostra uma sada deste programa.

A = [ 95 12 73 Inicio = 1

8 80

2 65 74 21 97]

Fim = 3 Menor valor entre 1 e 3 = 12, na posio 2 Inicio = 2 Fim = 10 Menor valor entre 2 e 10 = 2, na posio 6 Inicio = 0 Fim = 0
Figura 347: Uma sada do programa MinimoPos_teste

Com a confiana adquirida sobre a funo MinimoPos ns podemos chegar ao refinamento final da funo SelectSort, mostrado na Figura 348. function sA = SelectSort(A) for k = 1:length(A)-1 // Seleciona a posio entre A(k) e // A(length(A)) que contm o menor valor [Min iMin] = MinimoPos(A,k,length(A)); // Troca os valores de A(k) com o valor // na posio selecionada. temp = A(k); A(k) = A(iMin); A(iMin) = temp; end sA = A; endfunction
Figura 348: A funo SelectSort

Vamos agora examinar a complexidade deste algoritmo. Para ordenar um vetor de tamanho , o primeiro passo do algoritmo de seleo e troca realiza 1 comparaes; o segundo, 2; o terceiro, 3, e assim por diante, at chegar ao ltimo passo, quando feita uma nica comparao. Podemos concluir que o nmero de comparaes realizado dado por ( 1) 2 = 1 + 2 + + ( 1) = = 2 2 Para suficientemente grande, o nmero de comparaes se aproximar de 2 2. Ou seja, o nmero de comparaes necessrias para a execuo do algoritmo cresce com o quadrado do tamanho do vetor, e portanto o algoritmo de ordenao por seleo e troca (2 ). A Figura 349 mostra um grfico com medidas de desempenho obtidas para o mtodo de seleo e troca em dois computadores. Voc pode reparar que para ordenar um vetor com 5000 elementos o tempo gasto pelo computador mais rpido j significativo, da ordem de 1 minuto.
1

10 - Ordenao

215

Figura 349: Tempos medidos para ordenao por seleo e troca de vetores aleatrios em um notebook (*) e em um desktop (+)

10.2 Intercalao (MergeSort)


a 1 2 3 4 1 2 3 b 4 5 6

15 15 19 22
1 2

10 16 19 20 23 27
9 10

Intercalao de a e b 3 4 5 6 7 8

10 15 15 16 19 19 20 22 23 27
Figura 350: Uma operao de intercalao

Intercalao (em ingls, merge) o nome dado ao processo de produo de um vetor ordenado a partir de dois outros j ordenados, como mostrado na Figura 350. O algoritmo de ordenao por intercalao consiste em dividir o vetor de entrada em duas partes, ordenar cada uma delas separadamente, e depois obter o vetor ordenado realizando uma operao de intercalao. A ordenao por intercalao aplicada recursivamente a cada parte, a no ser que a parte a ser ordenada seja de tamanho 1, quando a recurso termina pois a parte j est trivialmente ordenada. A Figura 351 mostra um exemplo de ordenao por intercalao de um vetor com 16 posies. Na parte superior da figura as pequenas setas indicam divises de uma parte do vetor; na parte inferior (em vermelho) as pequenas setas indicam operaes de intercalao de partes j ordenadas.

10 - Ordenao

216

16

12 72 26 54 98 73 0 59 30 25 62 11 61 67 33 2 12 72 26 54 98 73 0 59 12 72 26 54 12 72 12 72 12 72 26 26 54 54 26 54 12 26 54 72 98 98 73 73 73 98 0 98 73 0 59 0 59 59 0 59 0 59 73 98 0 12 26 54 59 72 73 98 30 25 62 11 61 67 33 2 30 25 62 11 30 25 30 25 30 11 25 30 62 2 11 25 30 33 61 62 67 25 62 11 62 11 62 11 61 67 33 2 61 67 61 61 67 2 33 61 67 67 33 2 33 2 33 2

16

0 2 11 12 25 26 30 33 54 59 61 62 67 72 73 98
Figura 351: Exemplo de ordenao por intercalao com n = 16 = 24

Os pequenos nmeros no lado esquerdo da figura indicam o tamanho de cada parte. Como 16 uma potncia de dois, a estrutura de divises e intercalaes muito regular. A Figura 352 mostra um exemplo com um vetor de tamanho 10, quando nem sempre as duas partes resultantes de uma diviso (ou a serem intercaladas) tm o mesmo tamanho.
10

60 85 6 82 92 56 57 81 5 55 60 85 6 82 92 60 85 6 60 85 60 85 60 85 6 60 85 6 60 82 85 92 5 6 82 82 92 92 82 92 56 57 81 5 55 56 57 81 56 57 56 56 57 56 57 81 5 55 56 57 81 57 81 5 55 5 5 55 55

10

6 55 56 57 60 81 82 85 92

Figura 352: Exemplo de ordenao por intercalao com n = 10

O cdigo da funo MergeSort est mostrado na Figura 353. Voc deve reparar que o cdigo transcreve o algoritmo de forma bastante direta, e que pressupe a existncia de uma funo Merge que realiza as intercalaes.

10 - Ordenao function sA = MergeSort(A) if length(A) <= 1 then sA = A; else m = int((1+length(A))/2); sA = Merge(MergeSort(A(1:m)),... MergeSort(A(m+1:length(A)))); end endfunction
Figura 353: A funo MergeSort

217

A codificao da funo Merge (Figura 354) tambm bastante intuitiva. Voc deve reparar que: pA, pB e pM so ponteiros que indicam as posies em foco nos vetores fonte e no vetor resultado; O primeiro loop realiza a intercalao propriamente dita, a cada passo colocando em M(pM) o menor entre A(pA) e B(pB), e avanando adequadamente pA ou pB; este loop termina quando pA ou pB atinge o limite do seu vetor; O segundo loop s efetivamente executado quando a sada da fase de intercalao se deu pelo esgotamento dos elementos de B e consiste em copiar os elementos restantes de A em M; Da mesma forma, o terceiro loop s efetivamente executado quando a sada da fase de intercalao se deu pelo esgotamento dos elementos de A, e consiste em copiar os elementos restantes de B em M. function M = Merge(A,B) pA = 1; pB = 1; pM = 1 while pA <= length(A) & pB <= length(B) if A(pA) <= B(pB) then M(pM) = A(pA); pA = pA+1; else M(pM) = B(pB); pB = pB+1; end pM = pM+1; end // Esgota A while pA <= length(A) M(pM) = A(pA); pM = pM+1; pA = pA+1; end // Esgota B while pB <= length(B) M(pM) = B(pB); pM = pM+1; pB = pB+1; end endfunction
Figura 354: A funo Merge

16

12 72 26 54 98 73 0 59 30 25 62 11 61 67 33 2

10 - Ordenao
8

218
12 72 26 54 98 73 0 59 30 25 62 11 61 67 33 2

fcil ver que o nmero de operaes elementares de uma operao de intercalao de dois 4 12 72 26 54de tamanhos 98 73 0 59 e3025 62 da 11 ordem 61 de 67 33 2 + . Isso porque cada passo do vetores ordenados algoritmo produz um elemento do vetor de sada, cujo tamanho + . A complexidade da 2 12por 72 intercalao 26 54 98 73 pode 0 59 ser 30inferida 25 62 11da Figura 61 67 355. 33 2 ordenao
1

12

72 12 72

26

54 26 54

98

73 73 98

59 0 59

30 25 30

25

62 11 62

11

61 61 67

67

33 2 33

16 passos

12 26 54 72

0 59 73 98 0 12 26 54 59 72 73 98

11 25 30 62 2 11 25 30 33 61 62 67

2 33 61 67

16 passos
8

16 passos
16

0 2 11 12 25 26 30 33 54 59 61 62 67 72 73 98
Figura 355: Passos para ordenao por intercalao

Ali vemos o processo ilustrado para um vetor cujo tamanho uma potncia de 2, mas para outros tamanhos, podemos considerar como limite superior a complexidade exigida para a menor potncia de 2 que supere o tamanho do vetor. Vamos considerar apenas a fase de intercalao, ilustrada na parte inferior da figura, uma vez que as divises so feitas com pouco trabalho computacional. Repare que: para a ltima intercalao realizada, que gera o vetor ordenado de tamanho a partir de dois vetores ordenados de tamanho /2, so feitas no operaes. para cada intercalao no penltimo nvel, que geram vetores ordenados de tamanho /2 a partir de vetores de tamanho /4, so feitas no /2 operaes; como temos duas intercalaes neste nvel, teremos tambm no mximo comparaes. o mesmo vale para todos os nveis anteriores; como temos 2 () nveis, o nmero mximo de comparaes realizadas pelo algoritmo de ordenao por intercalao igual a 2 (), e o algoritmo portanto (2 ).

Para se ter uma idia da diferena de desempenho entre o algoritmo de seleo e troca e o algoritmo de intercalao, quando = 10, 2 = 100, e 2 = 31,22; quando = 1000, 2 = 1.000.000, e 2 = 9965, e por a vai.

4 = log2(16)

16 passos

10 - Ordenao

219

Figura 356: Comparao de desempenho SelectSort vs MergeSort

A Figura 356 mostra o resultado de testes de desempenho realizados com a funo MergeSort, comparado com o desempenho da funo SelectSort, A superioridade do MergeSort gritante, e se acentua com o aumento do tamanho do vetor ordenado.

Figura 357: Grfico de desempenho para a funo MergeSort

Na Figura 357 ns vemos nmeros de desempenho para o MergeSort obtidos com a ordenao de vetores bem maiores, para os quais esperar pelo SelectSort exigiria bastante pacincia.

10.3 Partio (QuickSort)


Considere um vetor como o da Figura 358. Ns dizemos que este vetor est particionado porque sua parte esquerda, com ndices de 1 a 4, s contm valores menores ou iguais a 100, e

10 - Ordenao

220

sua parte direita, com ndices de 5 a 9, s contm valores maiores ou iguais a 100. Se ordenarmos cada uma das partes de forma independente, o vetor completo estar ordenado, pois no h possibilidade de serem necessrias inverses de ordem entre elementos de diferentes parties. A Figura 359 mostra uma ilustrao grfica de um vetor particionado.

93

100 56

12

123 100 231 212 112

Figura 358: Um vetor particionado

Figura 359: Visualizao de um vetor particionado

O mtodo que veremos agora para se ordenar um vetor utiliza uma operao de partio do vetor segundo um piv, que um valor igual a um dos elementos do vetor. A partio, operao aplicvel somente a vetores com dois ou mais elementos, separa o vetor em trs partes: a da esquerda, contendo somente elementos menores ou iguais ao piv, a do meio, contendo somente elementos iguais ao piv, e a da direita contendo somente elementos maiores ou iguais ao piv.

possvel que algumas das partes resultantes seja vazia. O mtodo prossegue aplicando-se recursivamente s parties da esquerda e da direita, at se conseguir parties de tamanho 1 que esto trivialmente ordenadas. Este um dos algoritmos mais famosos da cincia da computao, tendo recebido o nome de quicksort.

10 - Ordenao
14 0 2 0 0 0 0 0 0 2 2 2 2 2 11 6 5 5 5 5 5 5 6 6 6 6 6 6 5 12 2 12 13 6

221

11 12 14 12 13 6 11 12 6 11 12 6 6 6 6 12 13 14 12 13 14
Esquerda Meio Direita x Piv

12 11 12 13 14 11 12 12 13 14 11 12 12 13 14

Figura 360: Exemplo de ordenao por partio (quicksort)

A Figura 360 ilustra o comportamento do algoritmo na ordenao de um vetor com 10 elementos. A cada partio o piv escolhido est sublinhado. function sA = quicksort(A) if length(A) <= 1 then sA = A; else [l,m,r] = partition(A); sA = [quicksort(l) m quicksort(r)]; end endfunction
Figura 361: A funo quicksort, que implementa o algoritmo de ordenao por partio

Assim como o algoritmo de intercalao, a implantao do quicksort por meio de uma funo recursiva uma expresso direta do algoritmo, como mostra a Figura 361.

Figura 362: Elementos a serem trocados de posio durante o processo de partio. A barra horizontal mostra o valor do piv.

As parties so feitas pela funo partition, mostrada na Figura 363.

10 - Ordenao

222

function [left,middle,right] = partition(A) pivot = A((1+int(length(A))/2)); inf = 1; sup = length(A); while sup >= inf while A(inf) < pivot inf = inf+1; end while A(sup) > pivot sup = sup-1; end if sup >= inf then temp = A(inf); A(inf) = A(sup); A(sup) = temp; inf = inf+1; sup = sup-1; end end left = A(1:sup); middle = A(sup+1:inf-1); right = A(inf:length(A)); endfunction
Figura 363: A funo partition

Diversos pontos so dignos de nota nesta funo: O piv escolhido como o elemento posicionado ao meio do vetor A. Isto no um requisito do algoritmo, que entretanto exige que o piv seja um dos elementos de A. Algumas verses escolhem o primeiro elemento do vetor como piv, enquanto outras sorteiam a sua posio; inf avana sempre para a direita, e sup para a esquerda; o loop principal pra quando estes dois ponteiros se cruzam; no primeiro loop interno, inf avana para a direita at encontrar um elemento com valor maior ou igual ao piv; no segundo loop interno, sup avana para a esquerda at encontrar um elemento com valor menor ou igual ao piv; os elementos encontrados nestes dois loops internos so trocados de posio, a no ser que inf e sup j tenham se cruzado; inf mantido de forma tal que, a qualquer momento, todos os elementos sua esquerda so menores ou iguais ao piv. Repare que isto vlido inicialmente, pois no existe nenhum elemento sua esquerda, e que mantido vlido por todos os comandos; sup mantido de forma tal que, a qualquer momento, todos os elementos sua direita so maiores ou iguais ao piv; a argumentao para esta afirmativa anloga empregada para a varivel inf;

No difcil ver que a funo partition realiza comparaes para dividir uma partio de tamanho . O comportamento do algoritmo de ordenao por partio fortemente dependente das escolhas de piv. No melhor caso, os pivs escolhidos so tais que cada partio divide o vetor ao meio e, por motivos similares aos colocados na anlise da complexidade do algoritmo de ordenao por intercalao, o quicksort (2 ). No pior caso, o piv tal que cada partio produz uma parte com um nico elemento e outra com 1 elementos, e o nmero de comparaes (2 ), to ruim como a ordenao por seleo e troca. Os piores casos do quicksort so geralmente pouco provveis, e seu desempenho em casos como os nossos testes com vetores aleatrios significativamente superior ao do mergesort.

10 - Ordenao

223

Figura 364: Comparao entre SelectSort, MergeSort e QuickSort

Figura 365: Comparao entre MergeSort e QuickSort

10 - Ordenao

224

Figura 366: Teste de desempenho do quicksort

Na Figura 366 ns mostramos os resultados obtidos com vetores randmicos de at 700.000 elementos, que j atingem o limite de memria disponvel no Scilab. Repare que em 60 segundos o MergeSort foi capaz de ordenar 50.000 elementos, e que, neste mesmo tempo, o Quicksort ordena 200.000 elementos. Os resultados so to bons que o crescimento da curva de tempo parece linear. Como sabemos que no melhor caso o tempo deveria crescer com (), fizemos outra curva para nos certificarmos da correo do nosso experimento, mostrada na Figura 367.

Figura 367: Elementos ordenados por unidade de tempo, em funo do tamanho do vetor

10.4 Dividir para Conquistar


Os algoritmos de ordenao por intercalao e por partio so exemplos de emprego de uma estratgia clssica em computao, chamada dividir para conquistar. Dado um problema de tamanho , o problema dividido em 2 ou mais subproblemas, cada um de tamanho estritamente menor que ;

10 - Ordenao

225

cada subproblema conquistado por aplicao recursiva da mesma estratgia, a no ser que o seu tamanho seja suficientemente pequeno para permitir uma soluo direta; as solues dos subproblemas so combinadas para resolver o problema original.

Na ordenao por intercalao a diviso em subproblemas simples, mas a combinao das solues dos subproblemas exige a intercalao. Na ordenao por partio a diviso em subproblemas exige a execuo do algoritmo de partio, mas a combinao das solues dos subproblemas consiste apenas em sua justaposio.

10.5 Ordenao por Radical

Figura 368: Um carto perfurado51

51

Punched_card.jpg (imagem JPEG, 24061160 pixels) - Redimensionada (29%), acessado 22 de junho de 2013, https://upload.wikimedia.org/wikipedia/commons/f/f3/Punched_card.jpg.

10 - Ordenao

226

Figura 369: A classificadora de cartes IBM Type 82, de 194952

Todos os algoritmos de ordenao que vimos na Seo 10 so algoritmos de ordenao por comparao, isto , algoritmos que usam comparaes entre os elementos a serem ordenados para efetuar seu trabalho. Em algumas situaes possvel obter algoritmos de outro tipo, utilizando caractersticas particulares dos elementos a serem ordenados. Por exemplo, se os elementos a serem ordenados so todos nmeros decimais com algarismos, o algoritmo de ordenao por radical (radix sort, em ingls) pode ser utilizado. Para explicar o algoritmo de ordenao por radical o melhor mostrar como uma classificadora de cartes perfurados (veja a foto na Figura 369) era utilizada para ordenar um conjunto de cartes segundo valores presentes em, digamos, trs colunas dos cartes. Uma pilha de cartes no ordenados era colocada no alimentador da classificadora, cujos controles eram ativados para distribuir os cartes nos escaninhos segundo o valor perfurado na coluna menos significativa.

52

IBM Card Sorters, acessado 22 de fevereiro de 2012, http://www.columbia.edu/cu/computinghistory/sorter.html#references.

10 - Ordenao

227

506 021 688 115 489 529 541 658 012 719 508 784 792

1 2 021 012 541 792

4 5 6 784 115 506

8 9 688 489 658 529 508 719

021 541 012 792 784 115 506 688 658 508 489 529 719

0 21 5 41 0 12 7 92 7 84 115 5 06 688 6 58 508 4 89 529 7 19

0 1 2 506 012 021 508 115 529 719

4 5 541 658

8 9 784 792 688 489

506 508 012 115 719 021 529 541 658 784 688 489 792

50 6 50 8 01 2 11 5 71 9 02 1 52 9 54 1 65 8 78 4 68 8 48 9 79 2

0 1 012 115 021

4 5 6 7 489 506 658 719 508 688 784 529 792 541

012 021 115 489 506 508 529 541 658 688 719 784 792

Figura 370: Etapas para ordenao por radical

Os cartes eram ento recolhidos para formar uma nova pilha, respeitando a sequncia dos escaninhos, de tal forma que os cartes na nova pilha estavam ordenados pelo algarismo menos significativo. O mesmo procedimento realizado regulando a classificadora para distribuir pelo segundo algarismo menos significativo, depois com o terceiro menos significativo, at se atingir o -simo algarismo, quando o vetor estar ordenado. A Figura 370 mostra as trs distribuies necessrias para a ordenao completa de um conjunto de cartes.

11 - Algoritmos Numricos

228

11 Algoritmos Numricos
Nesta seo ns apresentamos alguns algoritmos numricos para o clculo de integrais definidas e tambm para encontrar razes de uma funo (). Tais algoritmos tm utilidade para problemas cuja soluo analtica difcilmente obtida ou no existe. Ns desenvolvemos tambm uma funo para o clculo de utilizando srie de Taylor, clculo que est sujeito a problemas que podem resultar de operaes de truncamento e de arredondamento que decorrem do uso de um nmero fixo de bits na representao de ponto flutuante. Mais uma vez, estaremos desenvolvendo funes que j existem no Scilab: integrate e intg calculam integrais definidas, fsolve resolve sistemas de equaes no lineares, e exp calcula . Os mtodos numricos utilizados nas funes Scilab so muito mais sofisticados do que os que apresentamos aqui.

11.1 Integrao por Trapzios


O primeiro passo para se obter uma aproximao numrica de uma integral () a diviso do intervalo [, ] em subintervalos iguais.Com isso ns vamos obter + 1 pontos regularmente espaados, que vamos chamar de 1 , 2 , , +1 . Ns temos 1 = , +1 = e +1 = = ( ), para todo 1 .
O lado esquerdo de cada retngulo coincide com a curva
O lado direito de cada retngulo coincide com a curva

rea = f(xi).x
xi
xi+1
xi

rea = f(xi+1).x
xi+1

Figura 371: reas cobertas pelas somas de Riemann pela esquerda e pela direita para () = no intervalo [0,1]

A Figura 371 e a Figura 372mostram duas formas de se aproximar do valor da integral utilizando somas das reas de retngulos, conhecidas como soma de Riemann pela esquerda e soma de Riemann pela direita.

11 - Algoritmos Numricos

229

O lado esquerdo de cada retngulo coincide com a curva

O lado direito de cada retngulo coincide com a curva

Figura 372: Somas de Riemman pela esquerda e pela direita para a funo seno no intervalo [-1 3]

Podemos ver que a rea definida pela soma de Riemann pela esquerda dada por

= (1 ). + (2 ). + + ( ). = ( )
=1

enquanto a rea definida pela soma de Riemann pela direita dada por
+1

= (2 ) + (3 ) + + (+1 ) = ( )
=2

A medida em que o nmero de intervalos aumenta e o tamanho do intervalo diminui, as somas de Riemann vo se aproximando da rea sob a curva, como mostra a Figura 373.

Figura 373: Somas de Riemann com 16 intervalos

As frmulas das somas de Riemann levam diretamente s implementaes em Scilab, mostradas na Figura 374 e na Figura 375.

11 - Algoritmos Numricos function lrs = LeftRiemannSum(f,a,b,n) // Calcula a soma de Riemann esquerda da funo // f entre os pontos a e b com n intervalos x = linspace(a,b,n+1); delta_x = (b-a)/n; lrs = sum(f(x(1:n))) * delta_x; // Comente os comandos abaixo se voc no // quiser o grfico scf(); plot2d2(x,f(x),style=5,axesflag=5); plot2d3(x,f(x),style=5,axesflag=5); xx=linspace(a,b,50); plot2d(xx,f(xx)); endfunction
Figura 374: Funo para o clculo da soma de Riemann esquerda

230

function rrs = RightRiemannSum(f,a,b,n) // Calcula a soma de Riemann direita da funo // f entre os pontos a e b com n intervalos x = linspace(a,b,n+1); delta_x = (b-a)/n; rrs = sum(f(x(2:n+1)))* delta_x); // Comente os comandos abaixo se voc no // quiser o grfico scf(); plot2d2(x,[f(x(2:n+1)) f(b)],style=5,axesflag=5); plot2d3(x,[f(x(2:n+1)) f(b)],style=5,axesflag=5); xx=linspace(a,b,50); plot2d(xx,f(xx),axesflag=5); endfunction
Figura 375: A funo RightRiemannSum

Nestas funes, voc pode observar que: O primeiro parmetro de entrada, f, a funo cuja soma de Riemann ser calculada; Os parmetros a e b so os extremos do intervalo, e n o nmero de sub-intervalos; A funo sum do Scilab utilizada para o clculo da soma dos elementos de um vetor; Para o clculo das somas somente os trs primeiros comandos so necessrios; os comandos restantes se destinam ao desenho de grficos que ilustra a soma realizada.

No difcil ver que possvel obter uma aproximao melhor da rea sob a curva em um subintervalo se utilizarmos o trapzio definido pelo valor da funo nos limites de cada subintervalo, cono mostrado na Figura 376.

11 - Algoritmos Numricos

231

rea do sub-intervalo = x.(f(xi) + f(xi+1))/2

xi

xi+1

Figura 376: Aproximao por trapzios

A soma das reas dos trapzios dada por


= = (1 ) + (2 ) (2 ) + (3 ) (1 ) + ( ) ( ) + (+1 ) + + + + 2 2 2 2

(1 ) (+1 ) + (2 ) + (3 ) + + ( ) + ] 2 2

(1 ) + (+1 ) = [ + ( )] 2
=2

Uma funo que calcula uma integral por trapzios est mostrada na Figura 377. function area = TrapezoidalSum(f,a,b,n) // Calcula a rea sob a curva f entre a e b, // utilizando n intervalos e a frmula dos // trapzios x = linspace(a,b,n+1); delta_x = (b-a)/n; area = ( (f(x(1))+f(x(n+1)))/2 + ... sum(f(x(2:n))) ... )*delta_x; // Os comandos abaixo desenham um grfico scf(); plot2d(x,f(x),style=5,axesflag=5) plot2d3(x,f(x),style=5,axesflag=5); xx=linspace(a,b,50); plot2d(xx,f(xx),axesflag=5); endfunction
Figura 377: Funo para aproximao de integrais por trapzios

Para testar esta funo, vamos calcular sin() , cujo valor exato ns sabemos: 0

sin x = cos ( cos 0) = 2


0

Com 5 intervalos, o resultado da chamada TrapezoidalSum(sin,0,%pi,5) foi 1.9337656; com 50 intervalos (chamada TrapezoidalSum(sin,0,%pi,50)), o valor obtido foi 1.999342.

11 - Algoritmos Numricos

232

11.2 Bisseo
Ns sabemos que as razes de funes (ou zeros de funes) como um polinmio de 2 grau podem ser encontradas por frmulas analticas, mas isto no possvel para muitas outras funes. O mtodo da bisseo um algoritmo que serve para determinar numericamente uma raiz de uma equao () = 0, onde () uma funo contnua qualquer. Para dar incio ao algoritmo, precisamos de dois pontos e , sendo < , onde a funo assume sinais opostos, ou seja, ou bem () > 0 e () < 0, ou ento () < 0 e () > 0, como mostrado na Figura 378.

Figura 378: Exemplos de intervalos adequados para o mtodo da bisseo

Como a funo contnua, e como () e () tm sinais opostos, em pelo menos um ponto no intervalo [, ] a funo ser obrigada a cruzar o eixo dos , onde () = 0. possvel que o intervalo [, ] contenha mais de uma raiz, como na Figura 379.

Figura 379: Intervalo contendo mais de uma raiz de uma funo

Se () e () tm o mesmo sinal, o intervalo [, ] pode conter ou no uma raiz, como mostra a Figura 380.

11 - Algoritmos Numricos

233

Figura 380: Intervalos em que a funo no tem sinais opostos nos extremos podem conter ou no uma raiz

Se ()no for contnua, possvel que mesmo com (). () < 0 (ou seja, () e () tm sinais opostos) no exista nenhuma raiz no intervalo [, ].

Figura 381: Se a funo no for contnua, sinais opostos nas extremidades de um intervalo no garantem que ele contenha uma raiz

O mtodo da bisseo exige portanto que () seja contnua em um intervalo [, ] tal que (). () < 0. De uma forma similar ao algoritmo de pesquisa binria, a cada iterao a funo calculada no ponto mdio do intervalo, = ( + )/2.

11 - Algoritmos Numricos

234

Figura 382: Caso em que a raiz est " esquerda" do ponto mdio do intervalo

Temos trs casos possveis. No primeiro (Figura 382) verificamos que (). () < 0, e portanto que o intervalo [, ] contm pelo menos uma raiz, onde o algoritmo pode ser reaplicado.

Figura 383: Caso em que a raiz est " direita" do ponto mdio do intervalo

No segundo caso (Figura 383) temos (). () < 0, e o intervalo [, ] que contm pelo menos uma raiz. A terceira possibilidade de termos tido sorte e encontrado tal que () = 0. Ao fim de cada iterao, ou bem a raiz foi encontrada, ou o intervalo de busca foi reduzido metade. O algoritmo consiste na aplicao repetida deste passo, e termina quando o intervalo onde se encontra a raiz suficientemente pequeno para a preciso desejada. Podemos agora dar incio ao desenvolvimento de uma funo que encontre uma raiz de uma outra funo utilizando o mtodo da bisseo.

11 - Algoritmos Numricos function r = bissecao(f,a,b,tol) // se f contnua e se f(a).f(b) < 0, esta // funo calcula a raiz r com preciso menor ou igual // ao valor de tol endfunction
Figura 384: Cabealho da funo bissecao

235

A Figura 384 mostra uma primeira verso da funo bissecao contendo apenas o seu cabealho: O primeiro parmetro formal de entrada, f, a funo da qual se deseja encontrar a raiz; Os parmetros a e b so os limites do intervalo, e devem ser tais que f(a)*f(b) < 0; O parmetro tol a tolerncia, isto , um valor para o tamanho do intervalo de busca onde a preciso desejada considerada satisfatria; O parmetro de sada r a raiz encontrada.

Para testar a funo bissecao, ns precisamos: de uma funo contnua, de um intervalo onde a funo troca de sinal, e de conhecer o valor de uma raiz nesse intervalo para que seja possvel verificar o resultado.

b a
Figura 385: Grfico de () =

A funo () = sin , cujo grfico est mostrado na Figura 385, satisfaz a estes requisitos, pois: contnua; tem sinais opostos nos extremos do intervalo [2,4] , e portanto este intervalo contm uma raiz, e essa raiz .

A Figura 386 mostra uma implementao desta funo. Repare no uso do operador .*, de multiplicao elemento a elemento, ao invs do operador *, de multiplicao matricial. function y = exp_sin(x) y = exp(-x) .* sin(x); endfunction
Figura 386: A funo exp_sin

11 - Algoritmos Numricos

236

O grfico da Figura 385 pode ser obtido na console do Scilab com os comandos mostrados na Figura 387. A diretiva axesflag=5 faz com que os eixos sejam traados no ponto (0,0). -->exec("exp_sin.sci") -->x = linspace(0,2*%pi,101); -->y = exp_sin(x); -->plot2d(x,y,axesflag=5)
Figura 387: Comandos para obter o grfico da Figura 385 na console do Scilab

Com isso ns j podemos construir um programa testador para a funo bissecao, conforme mostra a Figura 388. O programa permite experimentar com diversos valores de tolerncia, comparando a raiz calculada com o valor de com 10 casas decimais. clear exec("exp_sin.sci"); exec("bissecao.sci"); tolerancia = input("\nTolerncia = "); while tolerancia > 0 raiz = bissecao(exp_sin,2,4, tolerancia); printf(" Raiz = %12.10f; \n Pi = %12.10f\n",raiz,%pi); tolerancia = input("\nTolerncia = "); end
Figura 388: O programa bissecao_teste.sce

Um primeiro refinamento da funo bissecao.sci o loop que, a cada passo, reduz metade o intervalo que contm a raiz. No cdigo mostrado na Figura 389 ns podemos observar que: o loop interrompido quando o tamanho do intervalo menor ou igual tolerncia fornecida pelo usurio, e o valor retornado como raiz o ponto mdio do intervalo. function r = bissecao(f,a, b, tol) // se f contnua e se f(a).f(b) < 0, esta // funo calcula a raiz r com preciso menor ou igual // ao valor de tol while b-a > tol // Reduo do intervalo que contm a raiz end r = (a+b)/2; endfunction
Figura 389: Primeiro refinamento da funo bissecao

O refinamento da reduo do intervalo simplesmente a codificao do mtodo da bisseo, como mostra a Figura 390. Repare que: quando f(a)*f(m) < 0, a funo faz b = m; quando f(b)*f(m) < 0, a funo faz a = m; quando f(m) == 0, a funo faz a = m e b = m.

11 - Algoritmos Numricos function r = bissecao(f,a, b, tol) // se f contnua e se f(a).f(b) < 0, esta // funo calcula a raiz r com preciso menor ou igual // ao valor de tol while b-a > tol // Reduo do intervalo que contm a raiz m = (a+b)/2; //Ponto mdio if f(a)*f(m) <= 0 then // [a,m] contm uma raiz b = m; end if f(m)*f(b) <= 0 then // [m,b] contm uma raiz a = m; end end r = (a+b)/2; endfunction
Figura 390: A funo bissecao

237

A Figura 391 mostra o resultado de um teste da funo bissecao, onde podemos ver o efeito da tolerncia fornecida pelo usurio sobre a preciso do clculo da raiz. Tolerncia = 1.0e-3 Raiz = 3.1411132813; Pi = 3.1415926536 Tolerncia = 1.0e-6 Raiz = 3.1415925026; Pi = 3.1415926536 Tolerncia = 1.0e-10 Raiz = 3.1415926536; Pi = 3.1415926536
Figura 391: Teste da funo bissecao

11.3 Srie de Taylor para exp(x) e Cancelamento Catastrfico


Do clculo sabe-se que, para qualquer real, pode ser calculado por uma srie de Taylor, que uma soma de infinitos termos com a forma abaixo: = 1 + ou, lembrando que 0! = 1,

2 3 + + + 1! 2! 3! !

=
=0

Esta srie converge para qualquer valor de . Ns podemos ver que, a partir do termo onde , ! cresce mais rapidamente que , e que o valor absoluto dos termos tende para zero quando tende para infinito. Queremos aqui construir uma funo Scilab que calcule por esta frmula, adicionando termos at que seu valor absoluto seja menor que uma tolerncia fornecida pelo usurio. J temos como escrever o cabealho da funo, como mostra a Figura 392.

11 - Algoritmos Numricos

238

function y = expTaylor(x,tol) // Calcula a soma dos termos // da srie de Taylor at o primeiro // termo com valor absoluto menor // que a tolerncia tol endfunction
Figura 392: Cabealho da funo expTaylor

Para testar esta funo, o programa expTaylor_teste, mostrado na Figura 388, l um valor para a tolerncia. Depois, repetidamente, l valores para a varivel x, calcula e compara os valores retornados pela funo expTaylor que ns desenvolvemos e pela funo exp fornecida pelo Scilab, que bastante confivel pois utiliza tcnicas muito sofisticadas de clculo numrico.
exec("expTaylor.sci"); tol = input("\ntol = "); x = input("\nx = "); while x ~= 999 expCalc = expTaylor(x,tol); printf("\n x exp(x) expTaylor(x) printf ("\n%12g %15.8e %15.8e %15.8e\n", ... x,exp(x),expCalc,exp(x)-expCalc) x = input("\nx = "); end
Figura 393: O programa expTaylor_teste.sce

Erro")

Para o desenvolvimento da funo expTaylor, ns devemos reparar que possvel obter , o -simo termo da srie a partir do termo anterior, pois = 1 = = 1 ! ( 1)!

Com isso ns chegamos forma final da funo expTaylor, mostrada na Figura 394. function y = expTaylor(x,tol) // Calcula a soma dos termos // da srie de Taylor at o primeiro // termo com valor absoluto menor // que a tolerncia tol Termo = 1; y = 1; i = 1; while abs(Termo) >= tol Termo = Termo * x / i; y = y + Termo; i = i+1; end endfunction
Figura 394: A funo expTaylor

Vamos primeiramente testar a funo para alguns valores positivos de x. Podemos ver na Figura 395 que os resultados so muito bons, com diferenas 16 ordens de grandeza menores que os valores calculados pelas duas funes.

11 - Algoritmos Numricos tol = 1.0e-40 x = 1 1 2.71828183e+000 2.71828183e+000 -4.44089210e016 x = 10 10 2.20264658e+004 2.20264658e+004 7.27595761e012 x = 30 30 1.06864746e+013 1.06864746e+013 -3.90625000e003
Figura 395: Resultados de testes da funo expTaylor com x positivo

239

Mas o teste com valores negativos nos reserva surpresas desagradveis, como mostra a Figura 396. Para x == -1, o erro inferior aos valores por 15 ordens de grandeza, muito bom. Para x == -10, o erro 8 ordens de grandeza menor que os valores calculados; v l. J com x == -20, o erro da mesma ordem de grandeza dos valores calculados, muito ruim. A casa cai mesmo com x==-30, quando o erro 9 ordens de grandeza maior que o valor correto, e, pior, o valor calculado para 30 negativo, sendo que uma funo estritamente positiva! tol = 1.0e-40 x = -1 -1 016 x = -10 -10 013 x = -20 -20 009 x = -30 -30 005

3.67879441e-001 3.67879441e-001 -1.11022302e4.53999298e-005 4.53999296e-005 1.39453573e2.06115362e-009 5.62188447e-009 -3.56073085e9.35762297e-014 -3.06681236e-005 3.06681237e-

Figura 396: Resultados de testes da funo expTaylor com x negativo

O que aconteceu? A frmula para a srie de Taylor provada matematicamente, e a funo expTaylor uma implantao direta da frmula, com pouca possibilidade de erros.

-->eps = 1.0e-23; -->y = 1.0e23; -->x = y + eps; -->x == y ans = x igual a y bit por bit! T
Figura 397: Exemplo de cancelamento catastrfico

A origem dos maus resultados est na aritmtica de ponto flutuante, que usa um nmero fixo de bits para representao da mantissa. Operaes aritmticas com nmeros com grandes diferenas de ordem de grandeza no funcionam corretamente, como mostra a Figura 397. O valor 1.0e-23 somado a 1.0e23 no altera o seu expoente, o que natural, mas tampouco altera a sua mantissa, que no possui bits suficientes para essa adio. O valor somado simplesmente perdido na operao, em um efeito que conhecido por cancelamento catastrfico.

11 - Algoritmos Numricos

240

~4.3e007 15 ordens de grandeza maior que o resultado correto

Figura 398: Grfico com valores absolutos dos termos da srie de Taylor para x == -20

A Figura 398 mostra um grfico com os valores absolutos dos termos da srie de Taylor para x == -20. O maior valor absoluto de um termo da ordem de 107 , e o valor correto para 20 da ordem de 109 . Ou seja, nas operaes aritmticas realizadas com os primeiros termos da srie os erros de truncamento podem ser bem maiores que o resultado final, e isso o que ocorre com o uso da funo expTaylor para o clculo de exponenciais de nmeros negativos. Como lio a tirar destes exemplos, voc deve ter muito cuidado ao operar com nmeros de valores com grandes diferenas de ordem de grandeza. A aritmtica de ponto flutuante melindrosa; use funes de bibliotecas, desenvolvidas por profissionais de clculo numrico, sempre que possvel. Por outro lado, no se deixe levar pelo pessimismo. Programas numricos funcionam como esperado na maior parte dos casos.

12 Complexidade de Problemas

242

12 Complexidade de Problemas
Para o problema da fatorao vimos um primeiro algoritmo com complexidade (2 ), e um outro, superior, com complexidade (22 ). Para o problema da ordenao, vimos o algoritmo de Seleo, com complexidade (2 ), e o MergeSort, com complexidade ( log ), bem superior. Criatividade e estudo de propriedades de um problema podem levar a melhores algoritmos; mas isto seria sempre possvel? Esta a questo central deste mdulo, que leva a conceitos fundamentais da Cincia da Computao.

12.1 Complexidade da Ordenao


fcil ver que a complexidade do algoritmo de ordenao por radical (), superior complexidade no pior caso do melhor algoritmo de ordenao por comparao que vimos, o MergeSort, que ( log ). Mas o algoritmo de ordenao por radical menos genrico. Se considerarmos apenas algoritmos de ordenao que s utilizam comparaes a situao diferente. Ns vamos agora ao objetivo central desta seo, que demonstrar que no existe nenhum algoritmo de ordenao por comparaes que tenha complexidade melhor que ( log ). Um algoritmo de ordenao por comparaes pode receber como entrada um vetor com elementos dispostos em qualquer ordem, e produz uma permutao destes elementos disposta em ordem crescente. Durante a sua execuo o algoritmo faz diversas comparaes entre os elementos do vetor de entrada. Ns vamos aqui modificar ligeiramente alguns algoritmos de ordenao, fazendo com que eles mantenham durante toda a sua execuo um registro das posies que cada elemento ocupava no vetor original. Essencialmente essa modificao consiste em adicionar um vetor de ndices com valores iniciais [1 2 3 ... n] e, a cada troca efetuada com o vetor a ser ordenado, trocar tambm os elementos correspondentes no vetor de ndices. Assim, como a ordenao de [321 12 609] produz o vetor [12 321 609], o vetor de ndices ao final da execuo do algoritmo dever, neste caso, conter [2 1 3], significando que o primeiro elemento no vetor ordenado tinha a posio 2 no vetor original, o segundo elemento no vetor ordenado tinha a posio 1 no vetor original, e que o terceiro elemento no vetor ordenado tinha a posio 3 no vetor original. Ns vamos tambm fazer com que os algoritmos de ordenao registrem as posies no vetor original dos elementos envolvidos em cada comparao feita durante sua execuo. Todo algoritmo de ordenao por comparaes faz alteraes em suas variveis, depois uma comparao entre elementos do vetor a ser ordenado, alguma ao seja sobre este vetor (como uma troca de posies entre dois elementos), seja sobre outras das variveis que utiliza; depois, outra comparao, e outra ao, at que o algoritmo termine. A sequncia de comparaes e de aes depende dos resultados das comparaes efetuadas.

12 Complexidade de Problemas
Comparao de elementos de ndices 2 e 3 no vetor original

243

Resultado de Comparao

ndices nos vetores originais dos vetores ordenados

Figura 399: rvore de decises para o SelectSort

Uma rvore de decises uma forma compacta de descrever o comportamento de um algoritmo de ordenao por comparaes quando submetido a diversos vetores de entrada. A Figura 399 mostra uma rvore de decises gerada pelo SelectSort, quando submetido a todas as permutaes de um vetor [a b c], onde a, b e c so valores distintos. A rvore de decises deve ser lida da seguinte forma: a primeira comparao sempre feita entre os elementos que esto nas posies iniciais 1 e 2; a segunda comparao depende do resultado da primeira: o se o elemento de posio inicial 1 for maior que o elemento de posio inicial 2, a segunda comparao feita entre os elementos de posies iniciais 2 e 3; o se o elemento de posio inicial 1 for menor que o elemento de posio inicial 2, a segunda comparao feita entre os elementos de posies iniciais 1 e 3

E assim por diante. Toda rota na rvore de decises termina em uma permutao com as posies no vetor inicial dos elementos do vetor ordenado. Ns vemos que o algoritmo de Seleo e Troca faz no sempre 3 comparaes para ordenar um vetor de 3 elementos.

Figura 400: rvore de decises para o algoritmo da bolha

Figura 401: rvore de decises para o Quicksort

12 Complexidade de Problemas

244

A Figura 400 mostra uma rvore de decises para o algoritmo da Bolha, e a Figura 401 para o Quicksort. Ns podemos ver que o algoritmo da Bolha faz no mnimo 2 e no mximo 4 comparaes para ordenar 3 elementos, e que o Quicksort faz no mnimo 4, e no mximo 6 comparaes para ordenar os mesmos 3 elementos (isso mesmo, o Quicksort tem um comportamento sofrvel para a ordenao de vetores pequenos).
Permutao 1

n elementos

rvore de Decises Algoritmo Arbitrrio

Permutao 2
Permutao 3

Permutao n!

Figura 402: rvore de decises para um algoritmo arbitrrio de ordenao por comparaes

O termo rvore usado em Cincia da Computao para designar estruturas hierrquicas. rvores so compostas por ns; o n no ponto mais alto da hierarquia a raiz da rvore. Parentescos so usados para designar relaes definidas por uma rvore: os ns imediatamente abaixo de um dado n so seus filhos, o n imediatamente acima de um n seu pai, e assim por diante. Ns sem filhos so chamados folhas. rvores so comumente desenhadas de cabea para baixo, com a raiz encima e as folhas embaixo. A Figura 403 mostra uma rvore binria, isto , uma rvore onde cada n tem no mximo 2 filhos.

Raiz

Folhas no tm filhos

Figura 403: Uma rvore binria

A profundidade de um n em uma rvore o nmero de passos necessrios para se chegar a ele, partindo da raiz (que, consequentemente, tem profundidade 0). A Figura 404 mostra as profundidades dos ns da rvore da Figura 403.

12 Complexidade de Problemas

245

p=0

p=1
p=2

p=3
Figura 404: Profundidade em uma rvore

Uma rvore de decises associada a um algoritmo de ordenao por comparao claramente uma rvore binria, onde os ns so as comparaes, e folhas so as comparaes que levam ao trmino do algoritmo e portanto a uma permutao de ndices. O nmero de comparaes realizadas por um algoritmo , no pior caso, a maior profundidade dessas folhas. Qualquer algoritmo correto de ordenao por comparao deve ser capaz de ordenar qualquer permutao de um vetor com elementos distintos. Cada permutao da entrada deve produzir, alm do vetor ordenado, uma permutao dos ndices no vetor inicial de sada. Portanto, para uma entrada de tamanho , a rvore de decises dever ter ! folhas, nmero total de permutaes dos elementos. Para conseguir um limite mnimo do nmero de comparaes necessrio para ordenar elementos, vlido para qualquer algoritmo de ordenao por comparaes, precisamos estabelecer uma relao entre o nmero de folhas e a profundidade mxima de uma rvore binria.

Figura 405: Uma rvore binria de profundidade tem no mximo folhas

No difcil acreditar que uma rvore binria de profundidade tem no mximo 2 elementos, fato ilustrado pela Figura 405. A menor profundidade mxima de uma rvore de decises associada a um algoritmo de ordenao dada portanto por: 2 ! ou 2 (!) = 2 (1) + 2 (2) + + 2 () Mas =1 2 () uma aproximao a soma de Riemann pela esquerda, com intervalos iguais a 1 para a rea sob a curva da funo 2 () entre = 1 e = , como mostra a Figura 406.

12 Complexidade de Problemas

246

log2 n

D=1

Figura 406: A soma dos logaritmos dos inteiros de 1 a n a soma de Riemann pela esquerda para log(n)

Podemos ento escrever


1 2 () 2 () = (2 () ) |1 = 2 () + 1 =1

Isso prova que o limite inferior para a complexidade de qualquer algoritmo de ordenao por comparaes (2 ).

12.2 Problemas NP-completos: O Problema do Caixeiro Viajante


Um caixeiro viajante precisa visitar cidades, percorrendo a menor distncia possvel, sem passar duas vezes pela mesma cidade, e retornando sua cidade de origem. Ele conhece a distncia entre duas cidades quaisquer de seu roteiro; um exemplo est mostrado na Figura 407. No existem estradas entre as cidades sem ligao no grafo.
1
6 5

2 3 3
2

3 3 4
7

Figura 407: Distncias entre cidades a serem visitadas pelo caixeiro viajante

Qual o melhor roteiro, isto , qual o roteiro com a menor distncia total, partindo da cidade 1? Na Figura 408 voc pode ver como a escolha de um roteiro influencia a distncia total.
1
6 5

1
2

1
2

6
2

6
2

2 3 3
2

3 3 3 3 4
7

3 3 3 3 4

3 3

12 Complexidade de Problemas D = 19 D = 22 D = 15

247

Figura 408: Algumas alternativas de roteiros para o caixeiro viajante

Um exame atento nos faz perceber que o roteiro mais direita na Figura 408 , dentre todos, o de menor custo. Descobrir o roteiro timo fica bem mais complicado quando temos mais cidades, como na Figura 409.
1 8 14
7 15 12 9

9
1

11
13

2 10 9 12 3 4 4

12 12
6

15 5 11

12
3

6 5

Figura 409: Um problema com 8 cidades

Temos muito mais alternativas a examinar; trs exemplos esto na Figura 410. Aqui tambm a alternativa mais direita a rota tima, fato que no fcil de se confirmar por um simples exame do problema. Precisamos do auxlio de um computador. Queremos construir um programa que, dado um conjunto de cidades e suas distncias, descubra o melhor roteiro para o caixeiro viajante.
1 8 14
7 15

1
11
13

9
1

12 9

2 10 9 12 3 4 4

8 14
7 15

9
1

12 9

11
13

2 10 9 12 3 4 4
14
7

8 8
1

12 9

11
13

2 10 9 12 3 4 4

12 12
6

15 5 11

12 12
6

15 5 11

12
15

15 5 11

12
6

12
3

6 5

12
3

12
3

6 5

6 5

D = 81 Vamos tentar uma soluo direta. Devemos:

D = 98

D = 64

Figura 410: Algumas alternativas de roteiros para o problema da Figura 409

1. Gerar todas as alternativas de roteiros; 2. Para cada roteiro, calcular o seu custo total; 3. Escolher o roteiro com menor distncia total. E como fazer para gerar todas as alternativas de roteiros? Temos que gerar todas as permutaes das cidades a serem percorridas. Para um problema com 4 cidades, as rotas a serem examinadas so (lembrando que a cidade 1 o ponto inicial e final, e portanto faz parte de qualquer circuito): 2 2 3 3 3 4 2 4 4 3 4 2

12 Complexidade de Problemas 4 4 2 3 3 2

248

Ns iremos precisar de uma funo que gere as permutaes de um conjunto de nmeros, cada nmero correspondendo a uma cidade. O Scilab j oferece a funo perms para isso, mas vamos aqui desenvolver uma funo equivalente. Vamos primeiramente definir um cabealho para uma funo permutations (Figura 411). Function p = permutations(A) // gera uma matriz p onde // cada linha uma permutao de A Endfunction
Figura 411: Cabealho da funo permutations

Precisamos agora de um algoritmo para gerar essas permutaes. O raciocnio , mais uma vez, recursivo: Se o vetor A de tamanho 1, ele j a nica permutao possvel; seno, devemos separar o primeiro elemento do vetor; gerar todas as permutaes dos elementos restantes (mesmo problema inicial, mas com um elemento a menos), e fazer uma justaposio do elemento separado com as permutaes obtidas; repetir este procedimento para os demais elementos do vetor.

Como exemplo, considere o processo de gerar todas as permutaes do vetor [2 3 4]. Ns devemos: Separar o elemento 2, e gerar todas as permutaes do vetor [3 4]; depois, concatenar 2 s permutaes obtidas; Separar o elemento 3, e gerar todas as permutaes do vetor [2 4]; depois, concatenar 3 s permutaes obtidas; Finalmente, separar o elemento 4, e gerar todas as permutaes de [2 3], e depois concatenar 4 s permutaes obtidas.

A funo permutations mostrada na Figura 412 uma implementao direta deste algoritmo.

12 Complexidade de Problemas function p = permutations(A) if length(A) == 1 then p = A; else p = []; for i = 1:length(A) B = permutations(OneOut(A,i)); [nl,nc] = size(B); for j = 1:nl p = [p ; [A(i) B(j,:)]]; end end end endfunction function b = OneOut(A,i) x = 1:length(A); b = A(x ~= i); endfunction
Figura 412: A funo permutations

249

Ela faz uso da funo OneOut, que implementa a operao de separar o i-simo elemento do vetor, e que um bom exemplo de uso das possibilidades oferecidas pelo Scilab para manipulao de matrizes apresentadas na Seo 6.7 (pg. 161). J podemos dar incio ao desenvolvimento do programa principal. A Figura 413 apresenta uma primeira verso, formada apenas por comentrios. // // // // // L a matriz de distncias Gera todas as rotas possveis Calcula o custo de cada rota Seleciona a de menor custo Imprime o resultado

Figura 413: Primeira verso do programa CaixeiroViajante.sce

Vamos atacar inicialmente a leitura da matriz de distncias. Queremos utilizar a funo fscanfMat para esta leitura, mas temos que levar em conta que: precisamos representar o valor infinito para distncias entre cidades sem conexo direta, e a funo fscanfMat s l nmeros.

Isto pode ser resolvido adotando a conveno de usar no arquivo de entrada o valor -1 para representar infinito. Com isto podemos construir um arquivo de distncias como mostra a Figura 414.

Figura 414 : Arquivo Distancias.txt com distncias entre as cidades mostradas na Figura 407

Este arquivo pode ser lido diretamente com fscanfMat. Aps a leitura, os elementos com valor -1 devem ser substitudos por %inf. Voc pode ver este cdigo na Figura 415, onde est destacado o comando que faz as substituies.

12 Complexidade de Problemas

250

// L a matriz de distncias Dist = ... fscanfMat(uigetfile("*.txt",pwd(),"Distncias")); // Substitui -1 por %inf Dist(Dist==-1) = %inf;
Figura 415: Leitura do arquivo com distncias

Para gerar as rotas e calcular seus custos, vamos usar a funo permutations da Figura 412, e tambm uma funo cost, que recebe como parmetros de entrada uma matriz D de distncias, e um vetor path, que contm os ndices das cidades que compem uma rota. [nl,nc] = size(Dist); //nl deve ser igual a nc Rotas = permutations(2:nc); [NL,NC] = size(Rotas); for i = 1:NL Custo(i) = cost(Dist,[1 Rotas(i,:) 1]); End function c = cost(D,path) c = 0; for i=1:length(path)-1 c = c + D(path(i),path(i+1)); end endfunction
Figura 416: Obteno de todas as rotas e clculo dos custos

Nos trechos de cdigo mostrados na Figura 416 voc deve reparar que: o vetor Rotas recebe todas as permutaes das cidades de 2 a n, e no de 1 a n, pois a cidade 1 sempre o ponto de partida e de chegada. a rota enviada (passada como parmetro real) para a funo cost o vetor formado pela cidade 1, acrescida das cidades que compem uma linha do vetor Rotas, acrescido novamente pela cidade 1.

12 Complexidade de Problemas // Resolve o problema do caixeiro viajante clear() exec("permutations.sci"); exec("cost.sci"); exec("OneOut.sci"); exec("SelecionaMenor.sci"); exec("PrintMatrix.sci"); // L a matriz de distncias Dist = fscanfMat(uigetfile("*.txt",pwd(),"Distncias")); PrintMatrix("Distncias",Dist); // Substitui -1 por %inf Dist(Dist==-1) = %inf; // Obteno das rotas [nl,nc] = size(Dist); //nl deve ser igual a nc Rotas = permutations(2:nc); // Calcula o custo de cada rota [NL,NC] = size(Rotas); for i = 1:NL Custo(i) = cost(Dist,[1 Rotas(i,:) 1]); if Custo(i) <> Exemplos(:,1) then end end // Seleciona a de menor custo Melhor = SelecionaMenor(Custo,1); // Imprime a melhor rota printf("\nA melhor rota "); PrintMatrix("Rota",[1 Rotas(Melhor,:) 1]); printf("com custo total = %d.",Custo(Melhor));
Figura 417: O programa CaixeiroViajante.sce

251

A Figura 417 mostra o programa completo, que tambm usa as funes SelecionaMenor (Figura 345, pgina 213) e PrintMatrix (Figura 346, pgina 213). Executando este programa com o arquivo Distancias.txt (Figura 414), ns vemos que a melhor rota [1 2 3 5 4 1] com custo total = 15, mostrada na Figura 408. Muito bem, temos um programa que resolve o problema do caixeiro viajante. Mas ser que com ele ns poderemos encontrar o melhor roteiro para visitar de avio todas as 27 capitais brasileiras? melhor nem tentar. Com cidades, temos ( 1)! permutaes a explorar. Para o exemplo com 5 cidades, so 4! = 24 possibilidades, fcil. Para 8 cidades, temos 7! = 5040 rotas a examinar, sem problemas, mas para as capitais brasileiras, so 26! 4 1026 permutaes a serem examinadas!

12 Complexidade de Problemas

252

Figura 418: Qual o melhor roteiro para visitar as 27 capitais brasileiras?

Mas isso no seria simplesmente um defeito do nosso algoritmo, cuja complexidade (!)? Repetindo a pergunta feita para os algoritmos de ordenao, seria possvel construir um algoritmo com complexidade polinomial para o caixeiro viajante? Efetivamente existem solues melhores, com tcnicas mais sofisticadas que reduzem significativamente o nmero de roteiros a serem examinados. Mas no reduzem tanto. A melhor soluo j encontrada53 tem complexidade (2 2 ), o que para suficientemente grande cresce mais rapidamente do que qualquer potncia de , ou do que qualquer polinmio em . Seno, podemos provar que no existe tal soluo? Infelizmente no temos uma boa resposta para estas duas questes. Aps dcadas de intensa pesquisa, no se conhecem algoritmos com complexidade polinomial para este problema, mas ningum conseguiu uma prova de que no existem. Cientistas da computao classificam problemas e algoritmos conforme sua ordem de complexidade: Problemas com complexidade polinomial cujo tempo cresce com alguma potncia de so enquadrados na classe P, e so considerados educados. Problemas cuja complexidade cresce com o tamanho da entrada mais rapidamente do que qualquer polinmio so chamados intratveis. Dentre os intratveis, a classe NP compreende os problemas onde, dada uma resposta, pode-se verificar se ela ou no uma soluo em tempo polinomial. Este o caso do problema do caixeiro viajante, pois se algum afirma ter encontrado uma rota com custo , esta afirmativa pode ser verificada com facilidade, somando-se os custos das etapas na rota proposta. NP no significa No Polinomial, mas No determinstico Polinomial. A idia que os problemas em NP so resolvidos em tempo polinomial por uma algoritmo no determinstico, que em uma fase inicial adivinha uma soluo, que depois testada. Um subconjunto de NP a classe dos problemas NP-completos, que so tais que qualquer problema em NP pode ser transformado em uma de suas instncias.

Outro exemplo de problema NP-completo o problema da mochila, que consiste em descobrir qual a melhor escolha a de maior valor total de objetos com pesos e valores a serem colocados em uma mochila que tem uma capacidade mxima que no pode ser ultrapassada.
53

Travelling salesman problem - Wikipedia, the free encyclopedia, acessado 11 de dezembro de 2012, http://en.wikipedia.org/wiki/Travelling_salesman_problem#Computational_complexity.

12 Complexidade de Problemas

253

Figura 419: Quais objetos devem ser colocados na mochila para se obter o maior peso total sem ultrapassar a capacidade da mochila?

Se voc conseguir desenvolver um algoritmo com complexidade polinomial para resolver o problema do caixeiro viajante ou o da mochila, ou provar que no existe tal soluo, voc ficar famoso, e ganhar um prmio de um milho de dlares!

12.3 Problemas indecidveis: O Problema da Correspondncia de Post


Vamos agora estudar um problema proposto pelo matemtico Emil Post em 1946. Considere um estoque ilimitado de domins de um nmero finito de tipos.
Tipo 1 100 1 Tipo 2 0 100 Tipo 3 1 00

Figura 420: Exemplo de domins para o problema da Correspondncia de Post

Todos os domins de um tipo tm um mesmo string de 0s e 1s na parte de cima e outro na parte de baixo. O problema da correspondncia de Post resolvido se voc encontrar uma seqncia de domins tal que os strings formados pela concatenao dos strings superiores e inferiores sejam iguais. A Figura 421 mostra uma soluo para o problema proposto na Figura 420.

100 1

0 100

1 00

100 1

1 00

100 1

100 1

1 00

0 100

0 100

1001100100100
Figura 421: Uma soluo com 7 domins

Vamos representar uma sequncia de domins por um vetor de ndices como [1 3 1 1 3 2 2], que significa um domin do tipo 1, seguido de um domin do tipo 3, seguido de dois do tipo 1, seguido de um domin do tipo 2, seguido por dois do tipo 2. Para resolver o problema de Post ns vamos novamente usar um algoritmo fora-bruta, que gera todas as sequncias possveis de domins, comeando pelas menores. Se tivermos 3 tipos

12 Complexidade de Problemas

254

de domins, as primeiras sequncias geradas so [1], [2], [3], [1 1], [1 2], [1 3], [2 1], [2 2], [2 3], [3 1], [3 2], [3 3], [1 1 1], [1 1 2], [1 1 3], [1 2 1], e assim por diante. Voc pode ver que a gerao das sequncias pode ser feita por um processo equivalente contagem em um sistema de base 3, sem o algarismo 0 e incluindo o algarismo 3. exec("ReadPostProblem.sci"); exec("Sucessor.sci"); exec("strPost.sci"); exec("WritePostSolution.sci"); exec("WritePostProblem.sci"); // Leitura do problema de Post [nTypes Up Down] = ReadPostProblem(); WritePostProblem(Up,Down); found = %f; seq = []; while ~found seq = Sucessor(seq,nTypes); upString = strPost(Up,seq); dnString = strPost(Down,seq); found = upString == dnString; if found then WritePostSolution(seq,Up,Down); end end
Figura 422: O programa Post.sce

A Figura 422 mostra o programa Post.sce, aonde: A funo ReadPostProblem usada para ler um problema de Post um conjunto de tipos de domins. Essa funo retorna um inteiro nTypes, o nmero de tipos de domins, e os vetores de strings Up e Down, que contero respectivamente os strings da parte de cima e da parte de baixo de cada tipo de domin no problema lido; A funo WritePostProblem imprime na tela os dados do problema lido; O programa executa um loop que explora todas as seqncias de domins extrados dos tipos lidos, parando se encontrar uma seqncia onde as concatenaes dos strings da parte superior e da parte inferior dos domins so iguais. A varivel seq contm uma seqncia de domins, que a cada passagem do loop substituda por sua sucessora, usando a funo Sucessor; A funo WritePostSolution usada para imprimir na tela uma soluo eventualmente encontrada; A funo strPost constri um string concatenando segundo uma sequncia dada os strings na parte superior ou na parte inferior dos domins.

12 Complexidade de Problemas

255

Figura 423: Tela do Bloco de Notas com um arquivo de tipos de domins para o problema de Post da Figura 420

Vamos comear pela leitura de um conjunto de tipos de domins. A Figura 423 ilustra o formato que escolhemos para arquivos com tipos de domins que descrevem um problema de Post. function [nTypes, Up, Down] = ReadPostProblem() PostFile = uigetfile("*.txt",pwd(),"Problema de Post"); da = mopen(PostFile,"r"); Lines = mgetl(da); Up = tokens(Lines(1)); Down = tokens(Lines(2)); [nTypes,nc]=size(Up); Endfunction
Figura 424: A funo ReadPostProblem

A funo ReadPostProblem (Figura 424) faz uso da funo tokens, fornecida pelo Scilab, que recebe um string como parmetro de entrada, e produz um vetor coluna, onde os elementos do vetor so strings que, no string de entrada, esto separados por brancos ou tabulaes. function WritePostProblem(Up,Down); printf("\nProblema de Post:\n"); [nl,nc] = size(Up); for i = 1:nl printf("%5s",Up(i)); end printf("\n"); for i = 1:nl printf("%5s",Down(i)); end endfunction
Figura 425: A funo WritePostProblem

A funo WritePostProblem (Figura 425) imprime na tela um problema armazenado nos vetores de strings Up e Down. function s = strPost(Strs,seq) s = ""; for i = 1:length(seq) s = s + Strs(seq(i)); end endfunction
Figura 426: A funo strPost

12 Complexidade de Problemas A Figura 426 mostra a funo strPost que constri a concatenao dos strings em uma sequncia de domins. function s = Sucessor(r,nTypes) // retorna o sucessor da sequncia r VaiUm = 1; for i = length(r):-1:1 if VaiUm > 0 then if r(i) < nTypes then r(i) = r(i) + 1; VaiUm = 0; else r(i) = 1; end end end if VaiUm == 1 then s = [1 r]; else s = r; end endfunction
Figura 427: A funo Sucessor

256

A funo Sucessor (Figura 427) gera, a partir de uma seqncia de domins, a seqncia seguinte no processo de contagem. Essencialmente ela soma 1 ao nmero formado pelos algarismos que compem a seqncia. A Figura 428 mostra alguns exemplos de uso desta funo. -->Sucessor([],3) ans = 1. -->Sucessor([2 3 1],3) ans = 2. 3. 2. -->Sucessor([3 3 3],3) ans = 1. 1. 1. 1.
Figura 428: Exemplos de uso da funo Sucessor

Finalmente temos a funo WritePostSolution (Figura 429) que imprime na tela a soluo encontrada, em um formato tabular.

12 Complexidade de Problemas function WritePostSolution(seq, Up, Down) printf("\nSoluo: %s\n",strPost(Up,seq)); for i = 1:length(seq) printf("%5d",seq(i)) end printf("\n"); for i = 1:length(seq) printf("%5s",Up(seq(i))); end printf("\n"); for i = 1:length(seq) printf("%5s",Down(seq(i))); end endfunction
Figura 429: A funo WritePostSolution

257

J podemos testar o nosso programa para ver se encontramos a soluo da Figura 421. Escolhendo como entrada o arquivo ProblemaPost.txt, vemos que o programa Post.sce efetivamente resolve este problema, produzindo a sada mostrada na Figura 430. Problema de Post: 100 0 1 1 100 00 Soluo: 1001100100100 1 3 1 1 3 100 1 100 100 1 1 00 1 1 00

2 0 100

2 0 100

Figura 430: Sada do programa Post.sce, alimentado com o arquivo da Figura 423.

Como voc j deve esperar, inferir desse primeiro sucesso que o nosso algoritmo resolve qualquer problema de Post ingenuidade.
1000
0

01
0

1
101

00
001

Figura 431: A menor soluo para este problema de Post uma sequncia de 206 domins!

Usando algoritmos mais sofisticados, possvel mostrar que a menor seqncia que resolve o problema da Figura 431 formada por 206 domins. Baseando-se em testes feitos pelo autor destas linhas, o tempo estimado para o programa Post.sce resolver este problema com um notebook seria de 10112 anos! Poderamos pensar que estamos diante de um problema como o do caixeiro viajante, mas mesmo isso otimismo. A correspondncia de Post pertence a uma classe de problemas chamados indecidveis. Enquanto em problemas np-completos o espao de busca cresce explosivamente com o tamanho da entrada, em problemas indecidveis o espao de busca simplesmente ilimitado. Traduzindo para o problema de Post, o fato de no existir nenhuma seqncia de tamanho que resolva um dado problema no quer dizer que no existam solues de tamanho maior que . A indecidibilidade se refere ao caso geral, e no a instncias particulares. Para algumas instncias, como nos casos da Figura 421 e da Figura 431, pode ser possvel encontrar uma soluo. Para outras, pode ser possvel demonstrar que no existe nenhuma soluo, como seria o caso de um problema onde em todos os domins o string da parte superior fosse mais longo que o da parte inferior.

12 Complexidade de Problemas
10 0 0 001 001 1

258

Figura 432: Um problema de Post sem soluo conhecida.

Resultados tericos provam que no existe nenhum algoritmo que, para qualquer instncia de um problema de Post, consiga decidir se existe ou no uma soluo. A Figura 432 mostra um problema de Post para o qual no foi possvel, at hoje, nem encontrar uma soluo, e nem tampouco provar que ele no admite nenhuma soluo.

13 Prximos Passos

260

13 Prximos Passos
Chegamos ao fim de nosso curso, onde vimos alguns dos conceitos fundamentais da cincia da computao. hora de rever brevemente estas idias para obter uma viso de conjunto, e tambm para apontar algumas direes para prximos passos. Computadores trabalham com informao, que pode ser digital (simblica) ou analgica; Um processador trabalha essencialmente com informao simblica, usando apenas dois smbolos, comumente notados 0 e 1; equipamentos de entrada e sada utilizam transformaes anlogo-digital ou digital-analgica quando conveniente. Um bit a unidade de memria capaz de armazenar um destes smbolos. Com bits, pode-se representar 2 coisas distintas; Um cdigo uma conveno para a interpretao de conjuntos de bits. Cdigos importantes incluem ASCII e UTF-8, para a representao de caracteres, binrios sem sinal, binrios em complemento de 2 para incluir tambm nmeros negativos, e ponto flutuante. As operaes booleanas NOT, AND e OR realizam transformaes muito simples de bits, mas tudo o que um computador faz atravs da composio destas operaes; Transistores podem ser utilizados para implantar circuitos chamados portas lgicas, que realizam as operaes booleanas. Transistores so implantados de forma extremamente compacta em semi-condutores, e realizam as operaes booleanas muito rapidamente. Portas lgicas podem teoricamente realizar qualquer transformao de informao; colocando a informao de entrada e a de sada codificadas em uma tabela da verdade, podemos construir um circuito que realiza a transformao desejada. Isso funciona perfeitamente para circuitos pequenos, como para a construo de um circuito de soma completa, capaz de somar duas variveis de um bit. O uso direto de portas lgicas para transformao de informao entretanto limitado por razes prticas. Para a soma de dois inteiros de 32 bits, teramos uma tabela da verdade com 264 1,8 1010. Um supercomputador que gastasse um nanosegundo (109 segundos) para processar cada entrada da tabela da verdade demoraria 585 anos para terminar o processamento. Por sua vez, circuitos de soma completa podem ser ligados em em cascata, em um arranjo que permite a soma de variveis de, digamos, 32 bits cada uma. Isto funciona para inteiros de 64 ou de 128 bits, mas dificilmente algum pensaria em construir um circuito para calcular a soma de 20 nmeros de 32 bits cada um. Com registradores, barramentos, unidade lgico-aritmtica e memria dispostos em um arranjo adequado, podemos usar sinais de controle para guiar o fluxo de dados e obter a soma de 20 ou mais nmeros de 32 bits, usando um acumulador e realizando uma soma de cada vez. O prximo e enorme passo a automao da emisso dos sinais de controle, com o uso de um programa armazenado na memria, composto por instrues que so interpretadas executadas por uma unidade central de processamento, Um computador portanto um circuito que transforma informao, que entretanto difere do circuito de soma porque a transformao realizada no fixa, mas ditada por outra informao o programa armazenado.

13 Prximos Passos

261

Trocando o programa, trocamos a transformao realizada. O ganho em fllexibilidade enorme, quando comparado com a construo de um circuito. Software macio; hardware duro. E programas podem conter loops, o que nos permite por exemplo calcular a soma de 50.000 ou mais nmeros de 32 bits faanha absolutamente impraticvel para um circuito combinatrio, que para isso deveria ter 50.000 32 = 3.200.000 bits de entrada. A construo de um programa mesmo pequeno em linguagem de mquina uma tarefa infernal, mas uma das principais utilidades dos computadores facilitar a construo de programas para computadores. Montadores ou assemblers so programas que permitem o uso de mnemnicos para a designar instrues e posies de memria. Mesmo sendo um avano sobre a programao direta em linguagem de mquina, a programao que se consegue com estes sistemas ainda muito detalhada, presa a uma arquitetura especfica, sendo propensa a erros e sem portabilidade. Compiladores e interpretadores so tambm programas, que tm como entrada programas escritos em uma linguagem de alto nvel, como Fortran, C ou Scilab, e que ou bem transformam estes programas em instrues de mquina a serem executados diretamente por um computador, ou como o caso do Scilab tm internamente uma mquina virtual, que interpreta o programa recebido como entrada. Linguagens de alto nvel oferecem abstraes que nos permitem escrever programas descries de transformao de informao de uma forma muito mais prxima do nosso raciocnio. O Scilab, em particular, nos permite guardar valores em variveis com um nome que podemos escolher. Esses valores podem ser numricos, caracteres, ou lgicos. Variveis Scilab so sempre matrizes; a linguagem oferece notaes para designao de partes de uma matriz. Variveis, constantes, chamadas de funes, parnteses e operadores podem ser combinados em expresses que resultam em valores Scilab, e que podem ser empregados em comandos de atribuio para alterar valores de variveis. A linguagem Scilab oferece tambm comandos de controle do fluxo de execuo, como o comando condicional if-then-else, e os loops while e for. Temos comandos de entrada e sada, como input e printf, e comandos para o tratamento de arquivos, como mopen e mclose, mgetl, fscanfMat e fprintfMat, que nos permitem usar armazenamento estvel para massas de dados potencialmente grandes. Um programa Scilab formado por um programa principal e por definies de funes Scilab. Programas e funes Scilab so armazenados em arquivos. Uma funo Scilab define parmetros formais de entrada e de sada. A chamada de uma funo Scilab define parmetros reais de entrada, que so expresses Scilab, e parmetros reais de sada, que so variveis que recebem os valores calculados pela funo para seus parmetros formais de sada. Funes Scilab podem conter comandos Scilab, variveis locais e chamadas de funes incluindo possivelmente chamadas prpria funo, em um arranjo recursivo. A recursividade pode simplificar muito o desenvolvimento de algoritmos, pois expressa de forma natural o seu comportamento. Funes so uma importante ferramenta de modularizao. Seu uso permite o desenvolvimento seja em momentos separados, seja por pessoas diferentes. Com o domnio de uma linguagem de programao ns pudemos atacar problemas de transformao de informao muito mais elaborados.

13 Prximos Passos

262

Problemas de transformao de informao so em princpio resolvidos por algoritmos mtodos que prescrevem sequncias de transformaes elementares, e que so convenientemente implantados por programas de computadores no nosso caso, programas Scilab. Usando a linguagem Scilab ns vimos diversos algoritmos para soluo de problemas como leitura, processamento e escrita de dados, usando inicialmente teclado e monitor, para pequenos volumes de dados, e depois arquivos, para grandes volumes de dados. Para dois problemas clssicos de transformao de informao ns vimos diversas solues: a pesquisa por um valor em um vetor, e a ordenao de um vetor. Ns vimos que algoritmos podem diferir e muito em sua eficincia no uso de recursos computacionais, como tempo de execuo ou quantidade de memria. O termo complexidade computacional de um algoritmo empregado para caracterizar suas exigncias destes recursos como uma funo do tamanho dos dados de entrada. Alguns problemas de transformao de informao tm limites inferiores para a complexidade de qualquer algoritmo que o resolva. A ordenao de um vetor, por exemplo, no melhor caso ( log()). Acredita-se que o limite inferior para uma classe de problemas conhecida como npcompletos, como o problema do caixeiro viajante, tem complexidade intrnseca crescente em taxa maior que qualquer polinmio em . Outros problemas so ainda piores. Para problemas chamados indecidveis, como o da correspondncia de Post, no existem algoritmos com um tempo limite garantido para qualquer entrada.

H muito o que se aprender em computao, pura ou aplicada s cincias e s engenharias, e diversas outras disciplinas podem extender o seu conhecimento nesta rea: Organizao de Computadores. O projeto de sistemas digitais e de computadores uma vasta rea, que normalmente estudada em disciplinas como Sistemas Lgicos, Organizao de Computadores, ou Arquitetura de Computadores. Metodologias para o projeto e implantao de circuitos digitais so vistas com maior profundidade, assim como aspectos tericos. Clculo Numrico. Nessa disciplina so vistos, como o nome indica, algoritmos para a soluo de problemas numricos, de grande importncia para todos os cientistas e engenheiros. Tipicamente so vistos algoritmos para encontrar zeros (razes) de funes (dos quais o mtodo da bisseo visto na Seo 11.2 um exemplo), para a soluo de sistemas de equaes lineares, para interpolao, para soluo de equaes diferenciais, para integrao numrica, e vrios outros. A preocupao com erros de arredondamento e de truncamento, e com a sua propagao tratada com muito maior profundidade. Algoritmos e Estruturas de Dados. Esta rea trata extensamente de algoritmos para ordenao e pesquisa (dos quais ns vimos alguns exemplos), do uso de estruturas de dados mais flexveis que matrizes, como listas, rvores e grafos, do casamento de padres, sempre com um tratamento bem mais rigoroso dos aspectos relacionados complexidade. Programao Orientada a Objetos. A programao orientada a objetos, ou POO, oferece estruturas lingusticas para uma definio elegante de dados e de formas de interao. A programao torna-se mais compacta e mais segura, permitindo um intenso reaproveitamento de cdigo. Nenhum programador mais srio pode se permitir desconhecer a POO, que foi introduzida j em 1967 com a linguagem Simula, e depois explorada com Smalltalk. Estas duas linguagens ainda sobrevivem, mas o uso de C++ e de Java hoje muito maior.

13 Prximos Passos

263

Bancos de Dados. Bancos de dados so sistemas de armazenamento que extendem muito o conceito de arquivos. Um SGBD (Sistema de Gerncia de Banco de Dados) como Oracle, PostGresSQL, MySQL, SQL Server, e outros, permite a recuperao de dados por perguntas (queries, em ingls. SQL quer dizer Standard Query Language) como me d a lista dos alunos de engenharia civil com idade entre 18 e 20 anos que j tenham cursado Programao de Computadores ou Clculo Numrico. SGBDs tratam tambm do controle de concorrncia, controlando o acesso simultneo a uma mesma base por diversos usurios, e garantindo a preservao de sua integridade. Sistemas Reativos. So sistemas que reagem a diversos estmulos de forma a, por exemplo, controlar um alto-forno, aumentando a combusto ao perceber uma baixa de temperatura, e diminuindo quando a temperatura do forno est alta. Sistemas operacionais como o Windows ou o Linux so tambm exemplos de sistemas reativos, controlando os estmulos recebidos pelos equipamentos de entrada e sada. Engenheiros e cientistas trabalham normalmente com sistemas reativos menores, controlando mquinas e equipamentos de laboratrios.

Para finalizar, alguns conselhos. O Scilab adequado para o desenvolvimento de pequenos programas voltados para cincias e engenharias. Para programas maiores, com mais de 1000 linhas, considere o uso de outras linguagens, com C, Fortran, C++ ou Java. Qualquer que seja a linguagem escolhida, procure usar bibliotecas de funes desenvolvidas por profissionais. S desenvolva o que for realmente necessrio. Funes de boas bibliotecas tm cdigo mais robusto e mais rpido, e do tratamento adequado a erros numricos. Experimente sempre! Enquanto voc no estiver fazendo programas para uso em produo, errar no machuca. Dificilmente um sistema se estraga por um erro de programao, e a experimentao essencial para o aprendizado.

***

Ns iniciamos este texto enumerando reas do conhecimento que foram ajudadas pela computao, mas vamos terminar com uma confisso. A rea que mais se beneficia com os resultados da Cincia da Computao ... a prpria computao. Computadores auxiliam a programar computadores, a construir circuitos que so usados por computadores, a projetar novas linguagens de programao, e tambm a construir programas que auxiliam o aprendizado de computao, como voc experimentou ao longo deste curso. este poderoso processo de auto-ajuda faz da computao o impulsor das mudanas de imenso impacto em nossas vidas.

ndice Remissivo

264

ndice Remissivo
%eps, 122 %pi, 122 .sce, 126 ABus, 270 acumulador, 89 lgebra Booleana, 45 algoritmo, 190 ALU, 91 ambiente Scilab, 119 AND, 46 Aritmtica matricial, 139 arquivo-programa, 126 rvore binria, 233 ASCII, 40 Assembler, 260 assembly, 260 atuadores, 28 barramento, 86 Basic, 117 Binrios sem Sinal, 42 bit, 21 bloco ento, 133 bloco seno, 133 Blue Gene, 13 bootstrap, 102 bps, 29 C, 117 C++, 117 Carta de tempo, 83 chamadas da funo, 177 ciclo de instruo, 260 Ciclo de Micro-Instruo, 275 Circuito para sincronizao, 269 circuito principal da CPU Pipoca, 267 Cleve Moler, 119 clock, 92 Cobertura dos 1s, 62 Cobol, 117 Codificao com Deslocamento, 43 cdigo da instruo, 263 Comandos Aninhados, 164 comentrios, 128 comparao de binrios sem sinal, 76 comparador de 1 bit, 76 compilador, 116 Complemento de 2, 43 complexidade computacional, 191 complexidade linear, 199 condutor perfeito, 51 console do Scilab, 120 Construindo matrizes, 143 controlled buffer, 86 converso binrio-decimal, 42 converses A/D, 22 converses D/A, 22 Correo, 190 data width, 85 DBus, 270 Debug, 270 Demultiplexadores, 79 desenvolvimento top-down, 184 diretrio corrente, 127 dividir para conquistar, 216 Dvorak, 28 eco, 121 supresso do eco, 122 Eficincia, 190 else, 133 endereo, 87 endfunction, 178 escopo de variveis, 179 Especificao, 190 estouro, 65 Expresses booleanas, 46 expresses lgicas, 130 eye, 144 fatorao de nmeros inteiros, 192 fetch, 280 flip-flop tipo D, 82 Flip-flops, 82 folhas, 233 Fortran, 116 fprintfMat, 170 fscanfMat, 170 funo recursiva, 186 Funes, 176 function, 178 George Boole, 45 getf, 180 GetOperand, 281 IBM PC, 12 IEEE 754, 44 if, 133 Indentao, 166

ndice Remissivo Informao, 18 Informao analgica, 18 informao digital, 18 input, 129 INPUT, 270 instrues, 262 instrues de desvio, 262 instrues de mquina, 260 Instruction Register, 261 Integrao por Trapzios, 218 Internet, 17 interpretador, 119 IR, 261 isolante perfeito, 51 Java, 117 jsr, 273 jump to subroutine, 273 kiss principle, 201 lmpada de 7 segmentos, 73 largura de bits, 85 leg, 172 legibilidade, 165 limites fisiolgicos, 27 linspace, 143 LISP, 118 loaders, 265 mantissa, 44 MAR, 88 Matlab, 119 matriz identidade, 144 matriz inversa, 141 matriz transposta, 141 Matrizes, 136 Matrizes de Strings, 150 meia-soma, 62 Memrias, 30 Memrias secundrias, 32 Memrias tercirias, 32 Memory Addres Register. See MAR merge, 207 mgetl, 169 micro Instruction Register, 272 micro Program Counter, 272 micro-assembler, 280 microinstrues de desvio, 273 microinstrues de sinal, 272 Micro-Programa, 280 microprogramao, 272 mIR, 272 mnemnicos, 264 modo de endereamento, 263 montador, 267 montagem, 260 mPC, 272 Multiplexadores, 79 NAN, 45 NAND, 49 nomes de variveis, 121 NOR, 49 NOT, 46 ones, 144 operadores relacionais, 130 operando, 263 OR, 46 ordenao, 202 ordenao por Intercalao, 207 Ordenao por Seleo e Troca, 202 oscilador, 92 Ou Exclusivo. See XOR OUTPUT, 270 overflow, 65 palavras, 87 Parmetros formais, 178 parmetros reais, 179 Pascal, 117 PC, 261 Pesquisa Binria, 199 Pesquisa Seqencial, 199 PHP, 117 pilha, 187 Planilha Pipoca.xls, 283 plot2d, 145 polgono, 172 Ponto Flutuante, 44 printf, 133 problema de transformao de informao, 190 processador, 20 produto elemento a elemento, 140 produto matricial, 140 profundidade, 234 Program Counter, 261 programa, 259 Programa em Execuo, 265 programa executvel, 264 Programa Executvel, 265 Programa Fonte, 265 programa principal, 177 Prolog, 118 prova formal, 190 pwd, 169 Python, 117 raiz da rvore, 233 RAM, 30

265

ndice Remissivo rand, 144 rect, 172 registrador, 84 registrador circular, 93 Registradores, 30 retorno da funo, 177 return, 273 Return Address, 272 RGB, 42 RoadRunner, 13 ROM, 87 sci, 180 Scilab, 119 SciPad, 126 seleo e troca, 203 Select Sort, 202 sensores, 28 SetInEmpty, 269 SetInFull, 269 Signals, 272 Sinal e Amplitude, 43 Sntese de Circuitos Combinatrios, 67 size, 137 software, 259 soma cannica, 62 soma de Riemann, 218 soma-completa, 65 somador de n bits, 65 splitters, 85 Strings, 131 sub-circuito, 70 SumX, 265 supercomputador, 14 tabela da verdade, 60 teclado Dvorak, 28 testes, 191 then, 133 timer, 192 Transistores, 48 Trocar os valores de duas variveis, 204 uigetfile, 168 unidade de controle, 262 unidade lgico-aritmtica, 91 vai-um, 64 Variveis, 121 variveis locais, 179 Variveis Lgicas, 134 varivel, 120 vem-um, 65 Vetores, 137 voltil, 30 volatilidade, 30 Von Neumann, 260 XOR, 54 xtitle, 172 zeros, 144

266

Referncias

267

Referncias
Andrews, D. (n.d.). Primes R US. Retrieved from http://www.geocities.com/primes_r_us/ Burch, C. (2002). Logisim: A Graphical Tool for Designing and Simulating Logic Circuits. Retrieved March 2009, from http://ozark.hendrix.edu/~burch/logisim/ Dijkstra, E. W. (1972). Chapter I Notes on Structured Programming. In E. W. O. J. Dahl, Structured Programming. Eds. ACM Classic Books Series. Academic Press Ltd., London, UK, 1-82. Flickr. (n.d.). Retrieved Fevereiro 2010, from http://farm4.static.flickr.com/3444/3348244651_fef16ef641.jpg Garey, M. R., & Johnson, D. S. (1979). Computers and Intractability: A Guide to the Theory of NP-Completeness. New York, USA: W. H. Freeman & Co. Hollasch, S. (2005). IEEE Standard 754 Floating Point Numbers. Retrieved August 25, 2009, from http://steve.hollasch.net/cgindex/coding/ieeefloat.html HotHardware.com. (n.d.). Intel Core 2 Extreme QX9770 Performance Preview. Retrieved Fevereiro 2010, from http://hothardware.com/articles/Intel_Core_2_Extreme_QX9770_Performance_Previ ew/ I.Ziller, J. B. (1954). Preliminary Report: Specifications for the IBM Mathematical FORmula TRANslating System, FORTRAN. International Business Machines, Applied Science Division. IBM. (n.d.). IBM Archives - Personal Computer. Retrieved 2009, from http://www03.ibm.com/ibm/history/exhibits/pc/pc_1.html Lohninger, H. (2006). (Vienna University of Technology) Retrieved from http://www.vias.org/simulations/simusoft_adconversion.html Lyon, B. (2005). The Opte Project. Retrieved August 2009, from http://opte.org/ Mathworks. (n.d.). Retrieved Fevereiro 2010, from http://www.mathworks.com/ McJones, P. (n.d.). History of FORTRAN and FORTRAN II. (Computer History Museum) Retrieved April 2009, from Software Preservation Group: http://www.softwarepreservation.org/projects/FORTRAN/ McKeeman, B. (n.d.). MATLAB 101 - A talk for the MIT Computer Science Department. Retrieved Fevereiro 2010, from http://www.cs.dartmouth.edu/~mckeeman/references/matlab101/matlab101.html Morris, R. J. (2003). The Evolution of Storage Systems. IBM Systems Journal, 42(2), 205-217. Neumann, J. v. (1945). Michael D. Godfrey home page. Retrieved Maro 2010, from http://qss.stanford.edu/~godfrey/vonNeumann/vnedvac.pdf O'Reilly Media. (n.d.). Language Poster. Retrieved April 2009, from History of Programming Languages: http://oreilly.com/news/languageposter_0504.html Scilab Consortium. (n.d.). Scilab Home Page. Retrieved from http://www.scilab.org/ StatLib. (1989). StatLib - Datasets Archive. (Department of Statistics, Carnegie Mellon University) Retrieved March 2009, from http://lib.stat.cmu.edu/datasets/ Top500. (n.d.). Top 500 supercomputers. Retrieved from http://www.top500.org

Referncias Wolffdata. (n.d.). Wolffdata. Retrieved 2008, from ScilabStarter: http://www.wolffdata.se/scilab/ScilabStarter.pdf Referncias Zotero

268

Alan M. Turing. On Computable Numbers, with an Application to the Entscheidungsproblem. Proceedings of the London Mathematical Society s2 42, no 1 (1937): 230265. Alan Turing - Wikipedia, the free encyclopedia. Acessado 11 de maro de 2011. http://en.wikipedia.org/wiki/Alan_Turing. An investigation of the laws of thought [microform]: on which are founded the mathematical theories of logic and probabilities: Boole, George, 1815-1864: Free Download & Streaming: Internet Archive. Acessado 19 de agosto de 2011. http://www.archive.org/details/investigationofl00boolrich. Applications with Scilab, Maxima, Geogebra. Acessado 28 de setembro de 2011. http://www.wolffdata.se/. ASCII - Wikipedia, the free encyclopedia. Acessado 18 de agosto de 2011. http://en.wikipedia.org/wiki/ASCII. Barbara Blackburn, the Worlds Fastest Typist. Acessado 15 de setembro de 2012. http://rcranger.mysite.syr.edu/famhist/blackburn.htm. Barret Lyon. The Opte Project. Acessado 7 de maro de 2011. http://opte.org/. bigbluesky2002. YouTube - Swiss Antique Music Box. Acessado 1 de abril de 2011. http://www.youtube.com/watch?v=-tzWt1X3oOg&p=66A384A130B0DCE4. Bill McKeeman. MATLAB 101 -- A talk for the MIT Computer Science Department, novembro de 2005. http://www.cs.dartmouth.edu/~mckeeman/references/matlab101/matlab101. html. Bryant, R.E., K. Sutner, e M.J. Stehlik. Introductory Computer Science Education at Carnegie Mellon University: A Deans Perspective. Tech. Report CMU-CS-10140, Carnegie Mellon University, Pittsburgh, 2010, http://link. cs. cmu. edu/article. php, 2010. Burch, Carl. Logisim. Acessado 20 de agosto de 2011. http://ozark.hendrix.edu/~burch/logisim/. . Logisim - a graphical tool for designing and simulating logic circuits. Acessado 7 de maro de 2011. http://ozark.hendrix.edu/~burch/logisim/. Chizmar, Jack. The Effective Teaching and Learning Network - training course and information for teachers - TQM and Classroom Research. Acessado 7 de maro de 2011. http://www.etln.org.uk/resources/page16.html. Claude Shannon - Wikipedia, the free encyclopedia. Acessado 19 de agosto de 2011. http://en.wikipedia.org/wiki/Claude_Shannon. Computer History Museum - Timeline of Computer History. Acessado 16 de fevereiro de 2012. http://www.computerhistory.org/timeline/?year=1946.

Referncias

269

Download PSPad - free unicode developer editor, handles near any syntax like HTML, PHP, XHTML, JavaScript, ASP, Perl, C and many other languages with HEX editor, multilanguage interface. Acessado 6 de maro de 2013. http://www.pspad.com/en/download.php. ENIAC - Wikipedia, the free encyclopedia. Acessado 16 de fevereiro de 2012. http://en.wikipedia.org/wiki/ENIAC. Euclidean algorithm - Wikipedia, the free encyclopedia. Acessado 8 de maro de 2011. http://en.wikipedia.org/wiki/Euclidean_algorithm#cite_note-2. File:MagneticMedia.png - Wikipedia, the free encyclopedia. Acessado 12 de agosto de 2011. http://en.wikipedia.org/wiki/File:MagneticMedia.png. File:Pdp-11-70-panel.jpg - Wikipedia, the free encyclopedia. Acessado 2 de setembro de 2011. http://en.wikipedia.org/wiki/File:Pdp-11-70-panel.jpg. George Boole - Wikipedia, the free encyclopedia. Acessado 23 de fevereiro de 2012. http://en.wikipedia.org/wiki/George_Boole. Home | TOP500 Supercomputing Sites. Acessado 7 de maro de 2011. http://www.top500.org/. IBM Archives: IBM Personal Computer. Acessado 7 de maro de 2011. http://www03.ibm.com/ibm/history/exhibits/pc/pc_1.html. IBM Card Sorters. Acessado 22 de fevereiro de 2012. http://www.columbia.edu/cu/computinghistory/sorter.html#references. John W. Backus et al. Preliminary Report: Specifications for the IBM Mathematical FORmula TRANSlating System, FORTRAN | Computer History Museum, 1954. http://www.computerhistory.org/collections/accession/102679231. Ken&Den picture. Acessado 24 de setembro de 2012. http://cm.bell labs.com/cm/cs/who/dmr/picture.html. Lawrence Livermore National Laboratory. BlueGene/L Photo Gallery. Acessado 11 de maro de 2011. https://asc.llnl.gov/computing_resources/bluegenel/photogallery.html. M. R. Garey, e D. S. Johnson. Computers and Intractability: A Guide to the Theory of NP-Completeness. First Edition. W. H. Freeman, [s.d.]. Magnetic-core memory - Wikipedia, the free encyclopedia. Acessado 12 de maro de 2011. http://en.wikipedia.org/wiki/Magnetic_core_memory. Mathworks. MathWorks - MATLAB and Simulink for Technical Computing. Acessado 7 de maro de 2011. http://www.mathworks.com/. Moores law - Wikipedia, the free encyclopedia. Acessado 3 de maro de 2013. http://en.wikipedia.org/wiki/Moore_Law. Muammad ibn Ms al-Khwrizm - Wikipedia, the free encyclopedia. Acessado 21 de agosto de 2012. http://en.wikipedia.org/wiki/Mu%E1%B8%A5ammad_ibn_M%C5%ABs%C4%81 _al-Khw%C4%81rizm%C4%AB.

Referncias

270

NCARs MSS exceeds 2 petabytes. Acessado 12 de agosto de 2011. http://www.cisl.ucar.edu/news/04/fotoweek/0729.mss2pb.html. Photographic film image. Acessado 7 de maro de 2011. http://farm4.static.flickr.com/3444/3348244651_fef16ef641.jpg. Punched_card.jpg (imagem JPEG, 24061160 pixels) - Redimensionada (29%). Acessado 22 de junho de 2013. https://upload.wikimedia.org/wikipedia/commons/f/f3/Punched_card.jpg. SciDAC Review - SIMULATION SCALE: In HPC Simulations, How Much is ENOUGH? Acessado 2 de agosto de 2011. http://www.scidacreview.org/0801/html/scale.html. Scilab Consortium. Home - Scilab WebSite. Acessado 7 de maro de 2011. http://www.scilab.org/. sciport-3.0.pdf. Acessado 7 de maro de 2011. http://www.dca.ufrn.br/~pmotta/sciport-3.0.pdf. Sosa, Carlos, e Knudson, Brant. IBM System Blue Gene Solution: Blue Gene/P Application Development. IBM Redbooks SG24-7287-03. Acessado 14 de fevereiro de 2012. http://www.redbooks.ibm.com/redbooks/pdfs/sg247287.pdf. Sound Transducer. Acessado 2 de agosto de 2011. http://www.electronicstutorials.ws/io/io_8.html. Steve Hollasch. IEEE Standard 754 Floating-Point. Acessado 7 de maro de 2011. http://steve.hollasch.net/cgindex/coding/ieeefloat.html. The History of Programming Languages - OReilly Media. Acessado 7 de maro de 2011. http://oreilly.com/news/languageposter_0504.html. The Prime Pages (prime number research, records and resources). Acessado 7 de maro de 2011. http://primes.utm.edu/index.html. Travelling salesman problem - Wikipedia, the free encyclopedia. Acessado 11 de dezembro de 2012. http://en.wikipedia.org/wiki/Travelling_salesman_problem#Computational_co mplexity. Unicode - Wikipedia, the free encyclopedia. Acessado 19 de agosto de 2011. http://en.wikipedia.org/wiki/Unicode.

Apndice A: A CPU Pipoca

271

Apndice A: A CPU Pipoca


Neste Apndice ns apresentamos a CPU Pipoca, em um nvel de profundidade destinado a professores e a alunos avanados. O circuito da Figura 135 tem os mesmos elementos bsicos de uma CPU (veja tambm a Figura 433), com memria, barramentos e registradores controlados por sinais, e uma unidade lgico aritmtica que realiza transformaes como somas, subtraes, etc. Um circuito assim tem teoricamente a mesma capacidade de processamento (de transformao de informao) de um computador. Dizemos teoricamente porque preciso que algum se disponha a manipular os valores de entrada e os sinais de controle, como j fizemos nos exemplos de fluxos de dados j apresentados. Ou seja, usar esse circuito para fazer a soma de 500.000 nmeros possvel, mas no executvel por um ser humano.

Figura 433: Elementos bsicos para processamento e registradores da CPU Pipoca

A idia central de um computador a automao da emisso de seqncias de sinais de controle segundo o desejo de uma pessoa, desejo este expresso por um programa. Queremos que este circuito transforme informao de maneira flexvel, com seu comportamento moldado por um programador. Trocando-se o programa, troca-se a transformao de informao produzida pelo circuito.

Figura 434: Um programa resolve um problema de transformao de informao

Considerando que queremos poder trocar com facilidade o programa que rege um computador, a nica opo colocar programas em uma memria, ao invs de implementlos com circuitos. O termo software, com o prefixo soft, macio, foi um neologismo criado para se contrapor a hardware, mais duro, constitudo por circuitos concretos. Software muito mais flexvel.

Apndice A: A CPU Pipoca

272

Figura 435: Um programa deve estar codificado em bits para ser carregado em alguma memria

Alguns dos primeiros computadores tinham uma memria para programas e outra para dados, mas na quase totalidade dos computadores atuais programas e dados so armazenados na mesma memria, seguindo a arquitetura chamada de Von Neumann, que props este arranjo em 1945 (Neumann, 1945). Um programa tem um carter dual, pois ele deve ao mesmo tempo: expressar a forma com que uma pessoa um programador pensa em resolver um problema de transformao de informao, e poder ser executado pelo processador, isto , por um circuito digital.

Figura 436: Programa Fonte e Programa Binrio

Na prtica estas duas demandas podem ser atendidas da seguinte maneira. Um programa composto por instrues de mquina, que so escritas por um programador em uma linguagem chamada Assembler, e depois traduzidas para serem executadas por uma CPU. Isso feito por um processo que chamamos de montagem (assembly) das instrues.

Figura 437: Montagem de um programa

A.1 Ciclo de Instruo


Tendo um programa carregado na memria, um computador executa repetidamente, incansavelmente, um ciclo de instruo.

Figura 438: Ciclo de execuo de instrues

Em cada ciclo uma instruo lida da memria e executada. A execuo da instruo:

Apndice A: A CPU Pipoca provoca alteraes nos contedos da memria e/ou dos registradores, e determina o endereo da prxima instruo a ser executada.

273

A coordenao do ciclo de instruo exige novos registradores na CPU. Na Pipoca, estes so: PC, de Program Counter, que contm o endereo da prxima instruo a ser executada IR, de Instruction Register, que contm a instruo em execuo Sinc Entrada e Sinc Sada, necessrios para sincronizar operaes de entrada e sada, que veremos mais tarde.

Figura 439: A coordenao da execuo de instrues na Pipoca exige registradores extras: PC (Program Counter), IR (Instruction Register), Sinc Sada e Sinc Entrada

Um ciclo de instruo se inicia pela leitura da instruo (ou instruction fetch) a ser executada. A instruo lida da memria, no endereo dado pelo contedo do registrador PC, e colocada no registrador IR.

Figura 440: Leitura de uma instruo

A execuo da instruo pode modificar o contedo da memria ou dos registradores, e determina um novo valor para o registrador PC o que significa determinar qual ser a prxima instruo a ser executada.

Apndice A: A CPU Pipoca

274

Figura 441: Execuo de uma instruo

Processadores so construdos de forma tal que a prxima instruo a ser executada est normalmente no endereo na memria subseqente ao ocupado pela instruo em execuo. Ou seja, as instrues em princpio so executadas na mesma sequncia em que se encontram armazenadas na memria. Instrues especiais, chamadas instrues de desvio, podem alterar essa ordem de execuo. Desvios podem condicionais, dependendo por exemplo do resultado de uma comparao. Um circuito chamado unidade de controle recebe como entradas o cdigo da instruo, o status de registradores de comparaes, um sinal de um oscilador (um clock), e se incumbe da gerao correta dos sinais de controle correspondentes que comandam o ciclo de instruo na CPU.

Figura 442: Uma unidade de controle e um clock so necessrios para a execuo de programas

Instrues

Para facilitar a programao, as instrues que constituem um programa no so estruturadas diretamente em termos de sinais de controle o que entretanto se poderia esperar, visto que a emisso destes sinais o efeito final necessrio para se produzir uma computao. Aes tpicas de instrues de mquina so somar o contedo da posio X de memria ao acumulador, ou ler um dado em pinos de entrada e colocar na posio de memria Y, com mais significado para o programador. A emisso efetiva dos sinais de controle fica definida

Apndice A: A CPU Pipoca pelo que chamamos de micro-instrues. A execuo de uma instruo feita atravs da execuo de vrias micro-instrues, como veremos a seguir.

275

15 14 13 12 11 10 OpCode Mode

5 4 3 Operand

Figura 443: Formato de uma instruo da Pipoca

Ns vimos que instrues devem ser codificadas tambm em bits. A Figura 443 mostra o formato que escolhemos para as instrues da Pipoca. Cada instruo tem 16 bits, sendo 4 para o cdigo da instruo, 2 para o modo de endereamento (que explicaremos a seguir) e 10 para um operando. Instrues so definidas em termos de alteraes na viso que um programador tem da CPU. O conjunto completo de instrues da Pipoca est mostrado na Tabela 5. So 11 instrues ao todo. Como dispomos de 4 bits para o cdigo da instruo, temos ainda espao para quatro outras instrues, que podem vir a ser implementadas em novas verses.
Tabela 5: Conjunto de instrues da Pipoca

Description
Adiciona o operando a ACC, deixando o resultado em ACC Compara o operando com ACC e coloca o resultado em Compare Para a execuo do programa Espera InFull = 1, e transfere o valor de Input para a palavra apontada pelo operando; faz InFull = 0 Desvia para a palavra apontada pelo operando Desvia para a palavra apontada pelo operando se "D=ACC" = 1 Desvia para a palavra apontada pelo operando se "D>ACC" = 1 Desvia para a palavra apontada pelo operando se "D<ACC" = 1 Carrega o operando no acumulador Espera OutEmpty = 1, e transfere o operando para o registrador Output; faz OutEmpty = 0 Transfere o valor de ACC para a palavra apontada pelo operando Subtrai o operando de ACC, deixando o resultado em ACC Estes cdigos podem ser usados para novas instrues

ADD COMPARE HALT INPUT JMP JMPEQ JMPGT JMPLT LOAD OUTPUT STORE SUB

0 0000 18 1 0001 1C 2 0010 45 3 4 5 6 7 8 9 10 11 12 13 14 15 0011 0100 0101 0110 0111 1000 20 27 2B 2D 2F 31

1001 36 1010 3B 1011 41 1100 1101 1110 1111

Nessa tabela, o campo Description descreve o efeito da instruo; o campo Mnemonic contm cdigos para cada instruo, que so empregados por um programador ao construir um programa; o campo OpCode10 enumera as instrues e, com isso, fornece um cdigo para cada uma delas; o campo OpCode2 contm os mesmos valores de OpCode10, mas codificados em binrio de 4 bits, destinados ao uso por computadores; O campo BranchTable16 ser explicado mais tarde.

Voltando Figura 443, os dois bits do modo de endereamento modificam a interpretao do campo de operando conforme a Tabela 6.

BranchAddr16

Mnemonic

OpCode10

OpCode2

Apndice A: A CPU Pipoca

276

Tabela 6: Modos de endereamento nas instrues da Pipoca

00 Endereamento imediato. O valor codificado no campo operando deve ser usado diretamente para a operao definida pela instruo. 01 Endereamento direto. O valor a ser usado na operao definida pela instruo o contedo da posio de memria cujo endereo est no campo operando da instruo. 10 Endereamento indireto. O valor a ser usado na operao definida pela instruo o contedo da posio de memria cujo endereo est na posio de memria cujo endereo est no campo operando da instruo. 11 Este cdigo para o modo de endereamento no utilizado na Pipoca.

Memria 7 23
Cdigo ADD ADD Modo Operando Imediato Direto Indireto 7 7 7 Efeito Soma 7 ao acumulador Soma 23 ao acumulador Soma 41 ao acumulador

23

41

ADD

Figura 444: Modos de endereamento

Supondo que em um dado instante a posio 7 da memria contenha o valor 23, e que a posio 23 da memria contenha o valor 41, uma instruo ADD com o valor 7 codificado em seu campo de operando ter como efeito: Se o endereamento for imediato, somar 7 ao contedo do acumulador; Se o endereamento for direto, somar o contedo da posio 7 da memria ao registrador no caso, somar 23 ao acumulador; Se o endereamento for indireto, somar o contedo da posio dada pelo contedo da posio 7 ao acumulador no caso, somar 41 ao acumulador.

Programao em Assembler

Um programa executvel um mapa da memria, contendo instrues e dados codificados em binrio. Entretanto, nenhum ser humano com sade mental consegue fazer um programa diretamente em binrio. O processo de programao em Assembler consiste em: preencher uma tabela com os mnemnicos das instrues, dando nomes a posies de memria e usando esses nomes como operandos, sendo assim mais compreensvel para humanos, e depois, substituir esses mnemnicos e nomes de posies de memria pelos cdigos binrios correspondentes, um processo a que damos o nome de montagem.

O programa em binrio deve ser gravado em alguma mdia hoje em dia, um arquivo, antigamente, fitas de papel ou cartes perfurados e, no momento da execuo, ser carregado na memria do computador. Na Pipoca, simulada no Logisim, isso equivale carga

Apndice A: A CPU Pipoca

277

de uma imagem na memria principal, o que possvel fazer clicando com o boto direito do mouse sobre o componente memria. Em computadores reais so programas chamados loaders que se incumbem de ler mdias com programas binrios e carreg-los na memria. Um mesmo programa tem portanto trs formas: Programa Fonte, que um texto em formato tabular, escrito e legvel por humanos; Programa Executvel, que resulta da montagem do programa fonte, e normalmente um arquivo com uma imagem da memria. No Logisim, um programa executvel um arquivo ASCII onde cada linha representa uma palavra da memria, codificada em hexadecimal, e Programa em Execuo, que um conjunto de palavras na memria principal.

A Tabela 7 mostra o cdigo fonte do programa SumX, cuja funcionalidade consiste em somar os valores na memria entre o endereo X e o endereo XEND. Ns vemos ali que o cdigo das instrues (do endereo 0 ao endereo 14) est junto com os dados (do endereo 15 ao 21). Esses dados consistem no vetor X, que ocupa as posies de 15 a 19, e em duas outras posies: SUM, que ir conter a soma desejada, e P, que ser utilizado para enderear a parcela de X que somada em cada passo da execuo do programa. Na Pipoca, o programa comea a ser executado pela instruo na posio 0 da memria. O programa SumX tem: Uma etapa de inicializao das variveis (posies de memria) SUM e P, formada pelas instrues nos endereos de 0 a 3, e que atribui o valor inicial 0 para SUM, e coloca em P o endereo X. Um loop composto pelas instrues colocadas entre o endereo 4 e o endereo 12. Em cada passo deste loop uma das parcelas adicionada a SUM, e o endereo armazenado em P incrementado. Ao fim do passo P comparado com XEND e, dependendo do resultado, o loop repetido ou o programa passa para a sua fase final. Uma etapa de finalizao, onde o resultado da soma encaminhado para a sada e o programa pra.

XEND
SUM P
Figura 445: Uso das variveis SUM e P no programa SumX.

As quatro ltimas colunas na Tabela 7 resultam de um processo de montagem que descrevemos a seguir.

Apndice A: A CPU Pipoca


Tabela 7: O programa SumX

278

Montagem do Programa Executvel


OpCode Mode Operand Instruo LOAD 1 SUM Cdigos 1000 01 0000010100 Binrio 1000 0100 0001 0100 Hexa 8414
Vem da tabela de cdigos de instruo SUM o nome dado posio x14 da memria

Figura 446: Montagem de uma instruo

A converso para binrio de uma linha de cdigo como LOAD 1 SUM se faz pelas etapas abaixo, ilustradas na Figura 446: Na Tabela 5 vemos que o cdigo da instruo LOAD 1000. O modo de endereamento codificado em binrio com 2 bits 01. Olhando o programa na Tabela 7, ns vemos que SUM o nome (label) dado posio 20 de memria, que, em binrio de 10 bits, 0000010100. A converso completa resulta da concatenao (justaposio) desses trs binrios, resultando em 1000010000010100 ou, em hexadecimal, 8414.

Apndice A: A CPU Pipoca

279

Como voc pode ter percebido, a traduo da tabela-programa para binrio uma tarefa insana. Mas essa tarefa s foi feita manualmente pelos pioneiros da computao com , pelos parmetros atuais, enormes custos de verificao e baixssima produtividade dos programadores. Mas cedo se percebeu que computadores eram muito bons para ... auxiliar a programao de computadores! Um montador (um assembler) um programa que l uma tabela-programa, e gera imagens binrias a serem carregadas nas memrias, automatizando o processo ilustrado na Figura 446.

Figura 447: O programa SumX, como um arquivo de imagem de memria do Logisim e carregado na memria

A Pipoca um circuito simulado no Logisim, onde mapas de memria podem ser carregados clicando sobre a memria com o boto direito do mouse e escolhendo a opo Load Image, que abre um dilogo para escolha de um arquivo como o mostrado na Figura 447. Arquivos como esse podem ser produzidos usando a planilha Pipoca.xls, disponvel no site do curso, e aqui utilizada como um assembler.

O Circuito Principal da CPU Pipoca

J temos agora condies de apresentar o circuito principal da CPU Pipoca, mostrado na Figura 448.

Apndice A: A CPU Pipoca

280

Figura 448: O circuito principal da CPU Pipoca

Complicado? Sem dvida, mas vamos por partes; mingau quente se come pelas beiradas. Primeiramente, voc deve reparar que neste circuito o principal complicador a unidade de controle, o retngulo vertical na parte inferior do circuito. Para ali vo muitos fios, e dali saem outros tantos. Isto no de se estranhar, posto que a funo da unidade de controle , como dissemos, levantar os sinais de controle na sequncia e tempos adequados para a implantao dos fluxos de dados que implementam as instrues de mquina. Como exemplos, esto destacados na Figura 448 cabeamentos para o sinal de clock do acumulador (em azul), para a tomada do barramento de dados pelo registrador Input (em vermelho) e para o campo operando da instruo (em marrom). O conjunto completo de entradas e sadas da unidade de controle est mostrado na Figura 449.

Apndice A: A CPU Pipoca

281

Estado da CPU

Propulsor

21 sinais de controle
Figura 449: Entradas e sadas da unidade de controle

O circuito principal da CPU Pipoca tem ainda circuitos auxiliares para sincronizao de entrada e sada, colocados na parte superior do diagrama, e um circuito para depurao ( debug) de programas, no canto inferior direito que, bloqueando o sinal de clock, permite que a execuo de um programa se interrompa ao trmino de cada instruo executada.
Sinal acionado pelo dispositivo de entrada Flip-flop Set/Reset

Sinal acionado pela Unidade de Controle

Vai para a Unidade de Controle

Figura 450: Circuito para sincronizao da CPU com dispositivo de entrada

O circuito mostrado na Figura 450 realiza a sincronizao da CPU com o (nico, na Pipoca) dispositivo de entrada. A sincronizao necessria porque, com a execuo automtica e incessante de instrues pela CPU, existe tanto a possibilidade de captura de dados nos pinos de entrada antes que estejam prontos, como a de captura repetida de um mesmo dado de entrada, como ainda a de mudana de dados pelo dispositivo de entrada antes de serem lidos pela CPU. O protocolo seguido pela CPU e pelo dispositivo prescreve as seguintes regras: Somente o dispositivo de entrada aciona o sinal SetInFull, e somente a CPU aciona o sinal SetInEmpty; O dispositivo de entrada somente aciona SetInFull quando o dado de entrada est pronto e InFull = 0, e a CPU (atravs da Unidade de Controle) somente aciona

Apndice A: A CPU Pipoca

282

SetInEmpty quando InFull = 1 (ou InEmpty = 0), o que feito aps a leitura dos dados de entrada; O circuito inicializado com InFull = 0.

O circuito de sincronizao com o dispositivo de sada similar a este. Na Pipoca, as instrues INPUT e OUTPUT exigem interveno do usurio, que deve usar a ferramenta de manipulao do Logisim para escolher valores de entrada e tambm para sincronizar dispositivos externos, apertando convenientemente os botes SetInFull(para avisar que um valor de entrada est pronto para ser lido) e SetOutEmpty(para avisar que um valor colocado anteriormente no registrador Output j foi consumido). Programas podem ser executados instruo por instruo, o que muito til para a depurao (debug) de erros. Para isto, preciso colocar o valor 1 na entrada Debug, e apertar o boto Run a cada vez que uma nova instruo carregada no registrador de instruo. Se retirarmos a Unidade de Controle da CPU Pipoca, retornando emisso manual dos sinais de controle, e se retirarmos tambm os circuitos de sincronizo de entrada e sada, teremos um circuito como o da Figura 451. Comparando com o circuito da Figura 135 voc pode observar que: foi acrescentado um registrador de instrues, o IR (Instruction Register) que tem a funo de armazenar a instruo em execuo num dado instante; temos um barramento de endereos, o ABus, alm do barramento de dados DBus; com a entrada ligada ao barramento de dados , e com a sada ligada ao barramento de endereos, ns vemos o registrador PC (Program Counter), que armazena o endereo da prxima instruo a ser executada; ns veremos adiante a lgica de funcionamento do PC; temos tambm conjuntos de leds ligados a decodificadores que no tm funo na lgica do circuito, mas nos ajudam a visualizar qual instruo est em execuo e qual o modo de endereamento empregado na instruo corrente.

Registrador de Instrues ABus

Contador de Programa

DBus
Figura 451: Rotas de dados na CPU Pipoca

Apndice A: A CPU Pipoca

283

O Contador de Programa

Outro subcircuito da CPU Pipoca o contador de programa, mostrado na Figura 452.

Figura 452: O contador de programa

Nesse circuito observamos que: o sinal Clock faz com que o registrador copie a sua entrada, que alimentada pela sada de um multiplexador; este multiplexador escolhe, segundo a entrada Force New Address, entre o valor corrente do registrador acrescido de 1 (resultado da operao de soma) e o valor constante na entrada New Address.

A unidade de controle se encarrega de colocar nessas entradas os valores adequados nos tempos corretos.

A Unidade de Controle

Figura 453: O papel da Unidade de Controle

A Figura 453 ilustra a funo da unidade de controle, que pode ser vista com mais detalhes no circuito da Figura 449. Para cumprir este papel a unidade de controle da Pipoca possui como principais componentes: um circuito Timing que fornece os sinais de tempo que conduzem a seqncia de eventos na unidade de controle, uma memria ROM (Read Only Memory) que contm uma tabela de desvios, a Branch Table, cuja funo explicaremos a seguir,

Apndice A: A CPU Pipoca uma outra ROM que abriga o microprograma, e registradores da unidade de controle.

284

Figura 454: Componentes da Unidade de Controle

Os registradores da unidade de controle da Pipoca so: o mPC (micro Program Counter), que contm o endereo da micro-instruo em execuo, o mIR (micro Instruction Register), que armazena a micro-instruo em execuo, o registrador Signals, cuja sada tambm a sada da unidade de controle, e que fornece os sinais de controle para a CPU, e o Return Address, que usado para permitir o uso de sub-rotinas, isto , de sequncias de micro-instrues que so reaproveitadas, como veremos a seguir.

Figura 455: Registradores da Unidade de Controle

A unidade de controle utiliza uma tcnica conhecida como microprogramao para produzir os sinais de controle que, emitidos nos momentos adequados para barramentos, registradores e memria, executam efetivamente os fluxos de dados que correspondem s instrues.

t 23

mOpCode
22 21 20

Reserve
19 18 17 16 15 14 13 12 11 10 9 8 7 6

mOperand
5 4 3 2 1 0

Signals
Figura 456: Formato de uma microinstruo

Em uma CPU microprogramada uma instruo executada como uma sequncia de microinstrues. Microinstrues da Pipoca tm 24 bits, no formato mostrado na Figura 456. Temos dois tipos de microinstrues: microinstrues de sinal, onde os bits de 0 a 22 so valores para os sinais de controle (clocks de registradores e memrias, controles de barramentos) que a unidade de controle deve prover para o circuito principal da CPU, ou

Apndice A: A CPU Pipoca microinstrues de desvio, que so utilizadas para guiar o fluxo de execuo das microinstrues.

285

O tipo da microinstruo ditado pelo bit mais significativo, o bit 23.


Tabela 8: Microinstrues de Desvio

m-Instruction DEC BIN jmpNext jmpIMMEDIATE jmpDIRECT jmpINDIRECT error return jsr jmpEQ jmpGT jmpLT jmp jmpInEmpty jmpOutFull 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001 10 1010

Effect Desvia para a micro-instruo inicial da instruo no registrador IR da CPU Desvia para o operando se o modo de endereamento for Imediato Desvia para o operando se o modo de endereamento for Direto Desvia para o operando se o modo de endereamento for Indireto Situao inesperada - no deveria acontecer. Acende um led. Desvia para a micro-instruo apontada pelo registrador Return Addr Desvia para o operando e armazena o endereo consecutivo no Return Addr Desvia para o operando se D = ACC for igual a 1 Desvia para o operando se D > ACC for igual a 1 Desvia para o operando se D < ACC for igual a 1 Desvia para o operando incondicionalmente

11 1011 Desvia para o operando se InEmpty = 1 12 1100 Desvia para o operando se OutFull = 1 13 1101 14 1110 15 1111 Estes cdigos podem ser usados em novas microinstrues

Instrues podem ter etapas comuns em sua execuo, como a obteno do operando conforme o modo de endereamento. O micro-cdigo destas etapas reaproveitado usando a micro-instrues jsr (jump to subroutine), que desvia para o endereo dado por seu operando, e armazena o endereo atual acrescido de 1 no registrador Return Address, e a microinstruo return, que desvia para o endereo armazenado no registrador Return Address. O circuito da unidade de controle pode ser visto na Figura 457, onde se pode destacar: as entradas o Opcode, com o cdigo da instruo corrente, o Mode, com o modo de endereamento, o In Empty, Out Full, com o estado dos registradores de sincronizao de entrada e sada,

Apndice A: A CPU Pipoca o

286

D>ACC, D=ACC, D<ACC, com o resultado da ltima instruo COMPARE executada, e o Reset Clock e CLOCK, que servem para inicializar o circuito Timing e para dar vida CPU; as sadas com sinais que controlam o fluxo de dados na CPU; a memria ROM Microprogram, que abriga o microprograma, com 256 palavras de 24 bits; a memria ROM Branch Table, com 16 palavras de 8 bits, que armazena para cada cdigo de instruo (Opcode) o endereo da primeira microinstruo a ser executada para a execuo da instruo; o registrador mIR (micro Instruction Register), com 24 bits, que armazena a microinstruo corrente; o circuito mPC (micro Program Counter), que funciona de forma anloga ao contador de programa da CPU; o registrador Return Addr, de 8 bits, que armazena o endereo de retorno para uma micro-instruo jsr; o circuito Timing, inicializado pela entrada Reset Clock e alimentado pelo CLOCK, que ciclicamente oferece os sinais t0, t1 e t2; o registrador Signals, que armazena os sinais utilizados no controle do fluxo de dados da CPU; um splitter ligando o registrador Signals aos pinos de sada; um decodificador de cdigo de instruo; um decodificador de modo de endereamento; portas lgicas que essencialmente implementam decises de desvio no fluxo de microinstrues; e alguns leds que animam a festa.

Apndice A: A CPU Pipoca

287

ROM Branch Table

Endereo de Retorno para jsr

Micro Program Counter


ROM Microprograma

Timing
Figura 457: A unidade de controle

O Ciclo de Micro-Instruo

Um ciclo de instruo na verdade implementado por diversos ciclos de micro-instruo, que, de forma similar aos ciclos de instruo, so compostos por etapas de leitura e de execuo de micro-instrues que se alternam indefinidamente.

Figura 458: Ciclo de micro-instruo

Na etapa de leitura, uma micro-instruo lida na ROM de microprograma, no endereo apontado pelo registrador mPC, e a instruo lida armazenada no registrador mIR.

Apndice A: A CPU Pipoca

288

Figura 459: Leitura de uma micro-instruo

A execuo da micro-instruo pode alterar os valores dos registradores da unidade de controle e, em particular, do registrador Signals que, como vimos, emite os sinais de controle para a CPU, e do registrador mPC, determinando assim a prxima micro-instruo a ser executada.

Figura 460: Execuo de uma micro-instruo

O mIR tem a interpretao de sua sada dependente do tipo da micro-instruo.

Figura 461: Sada do registrador mIR

O ciclo de micro-instruo comandado pelos sinais emitidos pelo circuito Timing.

Apndice A: A CPU Pipoca

289

Figura 462: Sinais do ciclo de micro-instruo

O circuito Timing est mostrado na Figura 463, sendo similar ao circuito da Figura 139.

Figura 463: O circuito Timing

As observaes abaixo podem ajudar a compreender o funcionamento da unidade de controle: O circuito Timing gera ciclicamente os sinais t0, t1 e t2; Quanto t0 passa de 0 para 1 (veja o destaque em vermelho na Figura 457), a microinstruo no endereo apontado por mPC carregada no mIR;

Figura 464: Aes em t0

Quando t1 passa de 0 para 1 (destaque em verde na Figura 457), se a microinstruo for do tipo signal, seu operando carregado no registrador Signals, cujas sadas fornecem os sinais de controle para a CPU; seno, se a microinstruo for jsr (jump subroutine), o valor do mPC acrescido de 1 armazenado no registrador Return Address

Apndice A: A CPU Pipoca

290

Figura 465: Aes em t1

Quando t2 passa de 0 para 1 (destaque em azul na Figura 457), o clock do mPC acionado, atualizando seu contedo, o que determina a prxima micro-instruo a ser executada. O novo contedo depende do sinal aplicado entrada Force New Address do mPC: o se for igual a 0, ser o endereo consecutivo ao contedo anterior; o se for igual a 1, ser o contedo da entrada New Address do mPC; O circuito que decide o valor aplicado entrada Force New Address um OR de vrias clusulas: o a microinstruo corrente jmp, jmpNext, ou return, ou jsr; o a microinstruo corrente jmpImmediate e o modo de endereamento Immediate, ou a microinstruo jmpDirect e o modo de endereamento Direct, ou a microinstruo jmpIndirect e o modo de endereamento Indirect; o a microinstruo corrente jmpGT e D>ACC = 1, ou jmpEQ e D=ACC = 1, ou jmpLT e D<ADD = 1; o a microinstruo corrente jmpInFull e InFull = 1, ou jmpOutEmpty e OutEmpty = 1.

Figura 466: Aes em t2

Quanto ao contedo da entrada New Address do mPC, isto , quanto ao endereo da prxima microinstruo a ser executada no caso de desvio, ele ser:

Apndice A: A CPU Pipoca o o contedo da memria Branch Table no endereo dado por OpCode se a microinstruo corrente for jmpNext,

291

Figura 467: Efeito da micro-instruo jmpnext

o o

o contedo do registrador Return Address se a microinstruo corrente for return, o contedo do campo operando da microinstruo se esta for jmp ou jsr, ou se a microinstruo for jmp<condio> e <condio> for igual a 1.

Micro-programa Branch Table


ADD COMPARE HALT INPUT JMP JMPEQ JMPGT JMPLT LOAD OUTPUT STORE SUB 0 1 2 3 4 5 6 7 8 9 10 11 18 1C 45 20 27 2B 2D 2F 31 36 3B 41

18 Micro-instrues para ADD 1C Micro-instrues para COMPARE 45

Micro-instrues para HALT ...

Figura 468: A Branch Table e o micro-programa

A Figura 468 mostra o relacionamento entre a Branch Table e o micro-programa.

Apndice A: A CPU Pipoca

292

O Micro-Programa

Figura 469: Construo do micro-programa e da Branch Table

Micro-programas tambm so feitos por humanos, os projetistas do computador. O processo de micro-programao consiste no preenchimento de uma tabela utilizando uma linguagem comumente chamada micro-assembler. Nesta linguagem utilizam-se labels para se referir a posies na memria de micro-programa, mnemnicos para as micro-instrues de desvio, e indicaes explcitas de quais sinais devem ser ativados para as micro-instrues de sinal. A tabela obtida o micro-programa fonte, legvel por humanos, a partir do qual processos de montagem produzem o micro-programa binrio e tambm a Branch Table.

t 23

mOpCode
22 21 20

Reserve
19 18 17 16 15 14 13 12 11 10 9 8 7 6

mOperand
5 4 3 2 1 0

m-Instruction

Signals
SetOutFull SetInEmpty In Clk In->DBus Out Clk RAM Clk RAM->DBus IR Clk Operand->DBus PC Clk PC Force PC->ABus MAR->Abus MAR Clk ACC Clk ACC Clear ACC->Dbus Subtract Comp Clk DR Clk DR->Dbus

mOperand

00 01 02 03 04

0 1 2 3 4

Fetch

jmpNext

0 0 0 0 1

New Signal New Signal

Comments

Addr(HEX)

Address

Label

Type

1 1

1 1

1 1 1

Sada do PC vai para Abus Sada da RAM vai para Dbus IR copia o Dbus PC avana Inicia a execuo da instruo armazenada no IR

Figura 470: Micro-cdigo para fetch de instruo

A Figura 470 mostra o micro-cdigo que implementa a leitura (fetch) de uma nova instruo. Este micro-cdigo executado ao fim de cada instruo; todas as instrues sempre terminam pela micro-instruo jmp Fetch. Repare que a ltima micro-instruo de Fetch jmpNext que, como vimos, desvia para a posio apontada pela sada da ROM Branch Table.

Apndice A: A CPU Pipoca


t 23

293
mOpCode
22 21 20

Reserve
19 18 17 16 15 14 13 12 11 10 9 8 7 6

mOperand
5 4 3 2 1 0

m-Instruction

Signals
SetOutFull SetInEmpty In Clk In->DBus Out Clk RAM Clk RAM->DBus IR Clk Operand->DBus PC Clk PC Force PC->ABus MAR->Abus MAR Clk ACC Clk ACC Clear ACC->Dbus Subtract Comp Clk DR Clk DR->Dbus

mOperand

18 00 19 01 1A 02 1B 03 04
41 42 43 44

24 ADD 0 Fetch 25 1 26 2 27 3 4

jsr

GetOperand

jmp
jmpNext
jsr

Fetch

1 0 0 0 0 0 1 0 1

New Signal New Signal

Comments

Addr(HEX)

Address

Label

Type

1 1

1 1

1 1 1

Resolve endereamento; operando efetivo no DR Sada do PC vai para Abus 1 Sada do DR vai para Dbus Sada da RAM vai para Dbus 1 ACC copia sada da ALU IR copia o Dbus Fetch da prxima instruo PC avana Inicia a execuo da instruo armazenada no IR

65 SUB 66 67 68

GetOperand

jmp

Fetch

1 0 0 1

1 1

Resolve endereamento; operando efetivo no DR 1 Sada do DR vai para Dbus; pino Subtract da ALU = 1 1 ACC copia a sada da ALU (=ACC - Dbus) Fetch da prxima instruo

Figura 471: Micro-cdigo para as instrues ADD e SUB

Na Figura 471 ns vemos o micro-cdigo das micro-instrues ADD e SUB. Ele se inicia com a micro-instruo jsr GetOperand; o micro-cdigo de GetOperand (Figura 472) se encarrega de resolver o modo de endereamento, colocando o operando efetivo da instruo no registrador DR.

t 23

mOpCode
22 21 20

Reserve
19 18 17 16 15 14 13 12 11 10 9 8 7 6

mOperand
5 4 3 2 1 0

m-Instruction

Signals
SetOutFull SetInEmpty In Clk In->DBus Out Clk RAM Clk RAM->DBus IR Clk Operand->DBus PC Clk PC Force PC->ABus MAR->Abus MAR Clk ACC Clk ACC Clear ACC->Dbus Subtract Comp Clk DR Clk DR->Dbus

mOperand

00 05 01 06 02 07 03 08 04 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17

0 5 1 6 2 7 3 8 4 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

Fetch GetOperand jmpIMMEDIATE jmpDIRECT jmpINDIRECT error Immediate jmpNext

Immediate Direct Indirect GetOperand

return Direct

return Indirect

return

0 1 0 1 0 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 0 0 0 1

New Signal New Signal

Comments

Addr(HEX)

Address

Label

Type

1 1

1 1

1 1 1

1 1 1 1 1 1 1 1 1 1 1 1

1 1 1

1 1

1 1 1 1 1

1 1 1

Sada do PC vai para Abus Sada da RAM vai para Dbus apropriadas Desvia para micro-instrues IR copia o Dbus PC avana Modo de endereamento inexistente??!! Inicia a execuo da instruo armazenada O operando da instruo vai para o Dbus no IR DR copia o Dbus Retorna O operando da instruo vai para o Dbus MAR copia o Dbus; sada do MAR vai para o Abus Sada da RAM vai para Dbus DR copia o Dbus Retorna O operando da instruo vai para o Dbus MAR copia o Dbus; sada do MAR vai para o Abus Sada da RAM vai para Dbus MAR copia o Dbus; sada do MAR vai para o Abus Sada da RAM vai para Dbus DR copia o Dbus Retorna

Figura 472: Micro-cdigo para a subrotina GetOperand

Com exceo da instruo HALT, o micro-cdigo de todas as outras micro-instrues invoca a sub-rotina GetOperand. No incio da execuo de GetOperand feito um desvio para sequncias micro-instrues que emitem os sinais de controle necessrios para a obteno do operando segundo o modo de endereamento. Essas sequncias tm os labels Immediate, Direct e Indirect, e todas as trs terminam com uma micro-instruo return, que retorna para o ponto onde a GetOperand foi chamada.
mOpCode
22 21 20

t 23

Reserve
19 18 17 16 15 14 13 12 11 10 9 8 7 6

mOperand
5 4 3 2 1 0

m-Instruction

Signals
SetOutFull SetInEmpty In Clk In->DBus Out Clk RAM Clk RAM->DBus IR Clk Operand->DBus PC Clk PC Force PC->ABus MAR->Abus MAR Clk ACC Clk ACC Clear ACC->Dbus Subtract Comp Clk DR Clk DR->Dbus

mOperand

00 27 01 28 02 29 03 2A 04 2B

2C 2D 2E 2F 30

0 Fetch 39 JMP 1 40 2 41 3 42 4 JMPEQ 43 44 45 JMPGT 46 47 JMPLT 48

jsr

GetOperand

jmp jmpNext jmpEQ jmp jmpGT jmp jmpLT jmp

Fetch JMP Fetch JMP Fetch JMP Fetch

0 1 0 0 0 1 1 1 1 1 1 1

New Signal New Signal

Comments

Addr(HEX)

Address

Label

Type

1 1

1 1

1 1

1 1 1

Sada do endereamento; PC vai para Abus operando efetivo no DR Resolve vai para Dbus 1 Sada da do RAM DR vai para Dbus; fora desvio no PC Dbus 1 IR PCcopia copiao Dbus PC avana Fetch da prxima instruo Inicia a condicional execuo dapara instruo Desvio JMP armazenada no IR

Fetch da prxima instruo Desvio condicional para JMP Fetch da prxima instruo Desvio condicional para JMP Fetch da prxima instruo

Figura 473: Micro-cdigo para as instrues JMP, JMPEQ, JMPGT e JMPLT

Apndice A: A CPU Pipoca

294

O micro-cdigo para as instrues de desvio est mostrado na Figura 473. Repare que o microcdigo das instrues de desvio condicional se inicia pelas micro-instrues de desvio condicional correspondentes. Se a condio de desvio no estiver satisfeita, nada acontece e a micro-instruo jmp Fetch executada para a leitura da prxima instruo.

t 23

mOpCode
22 21 20

Reserve
19 18 17 16 15 14 13 12 11 10 9 8 7 6

mOperand
5 4 3 2 1 0

m-Instruction

Signals
SetOutFull SetInEmpty In Clk In->DBus Out Clk RAM Clk RAM->DBus IR Clk Operand->DBus PC Clk PC Force PC->ABus MAR->Abus MAR Clk ACC Clk ACC Clear ACC->Dbus Subtract Comp Clk DR Clk DR->Dbus

mOperand

00 20 01 21 02 22 03 23 04 24 25 26
36 37 38 39 3A

0 INPUT Fetch 32 1 InLoop 33 2 34 3 35 4 36 37 38


54 OUTPUT 55 OutLoop 56 57 58

jsr jmpInEmpty

GetOperand InLoop

jmpNext

jmp
jsr jmpOutFull

Fetch
GetOperand OutLoop

0 1 0 1 0 0 1 0 0 1
1 1 0 0 1

New Signal New Signal

Comments

Addr(HEX)

Address

Label

Type

1 1

1 1

1 1 1

1 1

1 1

1 1 1

Sada do endereamento; PC vai para Abus operando efetivo no DR Resolve Sada da RAM vai Espera InEmpty = para 0 Dbus IR copia Dbus 1 Sada doo DR vai para Dbus PC avana 1 MAR copia o Dbus; sada do MAR vai para o Abus Inicia a execuo da instruo armazenada In copia a entrada; sada do In vai para Dbusno IR Zera o FF InEmpty; RAM copia o Dbus Fetch da prxima instruo
Resolve endereamento; operando efetivo no DR Espera OutFull = 0 1 Sada do DR vai para Dbus 1 Zera o FF OutFull; Out copia Dbus Fetch da prxima instruo

jmp

Fetch

Figura 474: Micro-cdigo para as instrues INPUT e OUTPUT

Na Figura 474 ns vemos o micro-cdigo para as instrues INPUT e OUTPUT que, logo aps a obteno do operando, executam um loop de espera composto por uma nica microinstruo, que executada repetidamente (atravs de um desvio condicional para ela mesma) at que a condio de sincronizao de entrada ou de sada esteja satisfeita.

t 23

mOpCode
22 21 20

Reserve
19 18 17 16 15 14 13 12 11 10 9 8 7 6

mOperand
5 4 3 2 1 0

m-Instruction

Signals
SetOutFull SetInEmpty In Clk In->DBus Out Clk RAM Clk RAM->DBus IR Clk Operand->DBus PC Clk PC Force PC->ABus MAR->Abus MAR Clk ACC Clk ACC Clear ACC->Dbus Subtract Comp Clk DR Clk DR->Dbus

mOperand

00 31 01 32 02 33 03 34 04 35

0 LOAD Fetch 49 1 50 2 51 3 52 4 53

jsr

GetOperand

jmpNext jmp

Fetch

0 0 1 0 0 1

New Signal New Signal

Comments

Addr(HEX)

Address

Label

Type

1 1

1 1

1 1 1
1

Sadaodo PC vai para Abus Zera ACC Sada da endereamento; RAM vai para Dbus Resolve operando efetivo no DR IR copia Dbus 1 Sada doo DR vai para Dbus PC avana 1 ACC copia sua entrada (= 0 + Dbus) Inicia a execuo instruo armazenada no IR Fetch da prxima da instruo

3B 3C 3D 3E 3F 40

59 STORE 60 61 62 63 64

jsr

GetOperand

jmp

Fetch

1 0 0 0 0 1

1 1 1

1 1 1

Resolve endereamento; operando efetivo no DR 1 Sada do DR vai para Dbus 1 MAR copia o Dbus; sada do MAR vai para o Abus Sada do ACC vai para Dbus RAM copia o Dbus Fetch da prxima instruo

Figura 475: Micro-cdigo para as instrues LOAD e STORE

O micro-cdigo para as instrues LOAD e STORE est mostrado na Figura 475, e no apresenta novidades.
mOpCode
22 21 20

t 23

Reserve
19 18 17 16 15 14 13 12 11 10 9 8 7 6

mOperand
5 4 3 2 1 0

m-Instruction

Signals
SetOutFull SetInEmpty In Clk In->DBus Out Clk RAM Clk RAM->DBus IR Clk Operand->DBus PC Clk PC Force PC->ABus MAR->Abus MAR Clk ACC Clk ACC Clear ACC->Dbus Subtract Comp Clk DR Clk DR->Dbus

mOperand

00 01 45 02 03 04

0 Fetch 1 HALT 69 2 3 4

jmp

HALT

jmpNext

0 0 1 0 0 1

New Signal New Signal

Comments

Addr(HEX)

Address

Label

Type

Figura 476: Micro-cdigo1para a instruo HALT

1 1

1 1 1

Sada do PC vai para Abus Sada da RAM vai para Dbus Loop infinito - parada final IR copia o Dbus PC avana Inicia a execuo da instruo armazenada no IR

A instruo HALT implantada por uma micro-instruo de desvio incondicional para ela mesma, o que coloca a CPU em um loop infinito, e para o processamento.

Apndice A: A CPU Pipoca

295

A Planilha Pipoca.xls

Para funcionar a Pipoca depende de ter preenchidas suas memrias RAM e ROM, o que pode ser feito no Logisim atravs da carga de arquivos com mapas de memria. Mas como fazer para obter mapas que correspondem a uma inteno do projetista de instrues ou do programador? Sua codificao direta bit por bit tarefa insana. O arquivo Pipoca.xls serve exatamente para isto, cumprindo as funes de assembler e de micro-assembler, como descrevemos nas prximas sees. Este arquivo contm as planilhas Microinstructions, Microprogram, Instructions, SumX, ReadX, SearchX e Aux. A planilha Microinstructions pode ser vista na Figura 477, e contm em cada linha um mnemnico da micro-instruo, seu cdigo em decimal e binrio, e uma descrio. Ali tambm pode ser vista a nica frmula utilizada, que utiliza a funo Excel DEC2BIN para converter um nmero decimal para binrio.

Figura 477: A planilha Microinstructions

A planilha Microprogram, mostrada na Figura 478 , de longe, a mais complicada no arquivo Pipoca.xls. As colunas onde o microprograma definido so aquelas com cabealhos de cor palha; as colunas com cabealhos de cor cinza so campos calculados. Passamos agora a descrever suas colunas. Colunas Addr(HEX) e Address. A coluna Address simplesmente uma enumerao de endereos consecutivos a serem ocupados na memria de microprograma, em decimal; a

Apndice A: A CPU Pipoca coluna Addr(Hex) obviamente sua converso para hexadecimal, muito teis para acompanhamento da execuo de um programa no Logisim.

296

Colunas Label, m-Instruction e Operand. nessas colunas que a parte de controle do microprograma definida. Para microinstrues de sinais estes campos devem ser mantidos vazios. Coluna Type. Essa coluna contm 0 se a microinstruo for de controle, e 1 se for de sinais, valor calculado por uma frmula que simplesmente verifica se a coluna m-Instruction da mesma linha est vazia. Colunas Signals. So os sinais que a unidade de controle deve enviar CPU quando a microinstruo for do tipo Signal. O micro-programador deve colocar 1s nas posies correspondentes aos sinais desejados. Coluna mOpCode(DEC). um campo calculado que tem o valor 0 se o campo m-Instruction estiver vazio na linha, e seno, o cdigo decimal da microinstruo obtida por pesquisa por seu mnemnico na planilha Microinstruction. Coluna Operand(DEC). um campo calculado que tem o valor 0 se o campo Operand estiver vazio na linha, e seno, o valor da coluna Address na linha onde o valor na Coluna Label igual ao campo Operand. Colunas Bin2Dec Conversion. Estas colunas fazem a converso para decimal de cada bit nas colunas Type e Signals, multiplicando o bit pela potncia de 2 correspondente sua posio na microinstruo. Coluna Microinstruction Word(DEC). Esta coluna contm o valor em decimal da palavra de 24 bits contendo a microinstruo. Para compreender sua frmula de clculo preciso examinar o formato das microinstrues, mostrado na Figura 456.

Figura 478: A planilha MicroProgram

O valor em decimal da micro-instruo igual soma: do campo Type multiplicado por 223

Apndice A: A CPU Pipoca do campo OpCode(DEC) multiplicado por 219; do campo mOperand. das potncias de 2 correspondentes a cada sinal igual a 1 na microinstruo.

297

Deve-se observar que quando Type = 1, a microinstruo de controle e todos os sinais so iguais a 0, e quando Type = 0 o campo OpCode(DEC) igual a zero, pois a microinstruo de sinais. Nas microinstrues de controle os bits de 8 a 18 no esto sendo utilizados. Coluna Microinstruction Word(HEX). simplesmente a converso para hexadecimal com 6 dgitos do valor decimal da microinstruo. A planilha Instructions est mostrada na Tabela 5, na pgina 275. Alm das colunas Description, Mnemonic, Opcode10 e Opcode2, que j comentamos, esta planilha contm a coluna BranchTable16, que calculada pesquisando para cada mnemnico de instruo o endereo hexadecimal da micro-instruo com label igual a este mnemnico na planilha Microprogram. esta coluna que deve ser utilizada para a produo de uma imagem de memria para a ROM Branch Table da Unidade de controle. 1.1.1.1 Programando a Pipoca As planilhas SumX e ReadX do arquivo Pipoca.xls contm programas em Assembler, e produzem imagens de memria a serem carregadas na RAM da CPU. Para explicar estas planilhas ns vamos mostrar como se constri um novo programa.

Figura 479: O programa SearchX

O primeiro passo consiste em copiar o cabealho de um dos programas j existentes em uma nova planilha, e ali codificar o seu programa, como mostrado na Figura 479. Aqui devem ser

Apndice A: A CPU Pipoca

298

colocados tambm os tamanhos de cada instruo ou varivel todos iguais a 1 neste programa. Depois, calcule os endereos, colocando 0 (zero) na primeira linha da coluna Address(DEC) e, nas linhas seguintes desta coluna, a frmula que soma o endereo e o tamanho da linha anterior para obter o endereo da linha corrente, como mostrado na Figura 480. Para obter os endereos em hexadecimal (muito teis para acompanhar a execuo do programa, pois o Logisim mostra endereos em hexadecimal), basta usar a frmula Excel DEC2HEX(Ci;2) para a linha i da coluna Address(HEX).

Figura 480: Clculo dos endereos - as setas destacam a clula C3 e sua frmula

Para obter o mapa de memria preciso agora colocar frmulas para calcular o valor de cada palavra neste mapa. Para isso, copie as colunas OpCode10, Operand10, Word10 e Word16 da primeira linha do programa SomaX, e cole somente as frmulas nas mesmas colunas da primeira linha do seu novo programa. Depois, selecione as clulas com as frmulas no novo programa, copie e cole nas linhas restantes nestas colunas, para obter a planilha completa mostrada na Figura 481.

Apndice A: A CPU Pipoca

299

Figura 481: Planilha completa com o programa SearchTable

As frmulas para as quatro colunas mais direita realizam pesquisas e clculos: Para a coluna OpCode10 (OpCode em decimal), a frmula para a clula H2
H2 =IF(ISBLANK(E2);0;INDEX(Instructions!C$2:C$18;MATCH(E2;Instructions!B$2:B$18;0)))

que diz ao Excel para colocar 0 se o campo de cdigo de instruo (E2) estiver vazio e, seno, efetuar uma pesquisa na coluna B da planilha Instructions procurando o cdigo da instruo (na coluna E2), obtendo assim seu cdigo decimal, que est na coluna C desta planilha. Para a coluna Operand10, a frmula para a clula I2
I2 =IF(ISBLANK(G2);0;IF(ISNUMBER(G2);G2;INDEX(C$1:C$36;MATCH(G2;A$1:A$36;0);1)))

dizendo ao Excel para colocar 0 se o campo de operando (G2) estiver vazio e, seno, se o operando for um nmero, colocar este nmero diretamente; se o operando for uma referncia, pesquisar pelo operando na coluna de labels (A), obtendo o valor do endereo correspondente. Para a coluna Word10, a frmula para a clula J2
J2 = H2*2^12+F2*2^10+I2

que calcula o valor em decimal da instruo, com potncias de 2 escolhidas segundo o posicionamento do termo na palavra de 16 bits como mostrado na Erro! Fonte de referncia no encontrada.. Para a coluna Word16, a frmula para a clula K2
H2 = DEC2HEX(J2;4)

que converte o valor decimal para um hexadecimal com 4 dgitos.

Apndice A: A CPU Pipoca

300

Figura 482: Arquivo com imagem de memria para o programa SearchTable

Para obter um arquivo com o mapa de memria que pode ser lido pelo Logisim, use o Bloco de Notas para criar um arquivo SearchTable.txt, e digite v2.0 raw em sua primeira linha; depois, copie todos os valores na coluna Word16 da planilha com o programa, e cole no Bloco de Notas, a partir da segunda linha. A Figura 482 mostra a janela do Bloco de Notas com o programa executvel.

Salve o arquivo; seu programa estar pronto para ser executado.

Você também pode gostar