Você está na página 1de 291

INTRODUO ORGANIZAO E

PROGRAMAO DE COMPUTADORES
USANDO LOGISIM E SCILAB

OSVALDO CARVALHO

DEPARTAMENTO DE CINCIA DA COMPUTAO


UFMG

1 SEMESTRE DE 2016

Contedo

Contedo
1

Computadores e Informao .............................................................................................. 12


1.1

Computadores ............................................................................................................. 14

1.2

Mdulos ...................................................................................................................... 20

1.3

Informao Analgica e Digital ................................................................................... 24

1.4

Computadores e Informao ...................................................................................... 27

1.5

Converses anlogo-digital e digital-analgica ........................................................... 28

1.6

Sensores e atuadores .................................................................................................. 34

1.7

Memrias .................................................................................................................... 35

1.8

Organizao do Contedo ........................................................................................... 39

Circuitos Combinatrios ...................................................................................................... 46


2.2

Bits e cdigos ............................................................................................................... 48

2.3

lgebra de Boole ......................................................................................................... 53

2.4

Portas Lgicas e Transistores ...................................................................................... 56

2.5

Introduo ao Logisim ................................................................................................. 60

2.6

Soma de duas parcelas de 1 bit ................................................................................... 66

2.7

Soma de dois inteiros com vrios bits ......................................................................... 70

2.8

Modularizao e Sntese Automtica de Circuitos Combinatrios no Logisim ........... 74

2.9

Sntese de um display hexadecimal ............................................................................ 80

2.10

Comparao de binrios sem sinal.............................................................................. 82

2.11

Multiplexadores, Demultiplexadores e Decodificadores ............................................ 86

Circuitos Sequenciais........................................................................................................... 90
3.2

Flip-flops e Registradores ............................................................................................ 92

3.3

Barramentos e Controle de Fluxo de Dados ............................................................... 96

3.4

Memrias .................................................................................................................... 97

3.5

Acumuladores e Loops ................................................................................................ 99

3.6

Uma Calculadora ....................................................................................................... 100

3.7

Clocks......................................................................................................................... 102

Processadores ................................................................................................................... 106


4.2

Programa Armazenado ............................................................................................. 108

4.3

CPU-0: Um Primeiro Processador ............................................................................. 111

4.4

CPU-1: Processador com Instrues de Desvio ......................................................... 116

4.5

CPU-2: Processador com Instrues de Desvio Condicional ..................................... 119

Contedo
4.6
5

CPUs Reais: Instrues e Programao em Assembler ............................................. 122

Programas Scilab ............................................................................................................... 126


5.2

Compiladores, Interpretadores e Sistemas Operacionais ......................................... 128

5.3

Scilab ......................................................................................................................... 132

5.4

Variveis e Comandos de Atribuio......................................................................... 133

5.5

Usando o Scilab como Calculadora ........................................................................... 137

5.6

Programas Scilab ....................................................................................................... 139

5.7

Valores Lgicos e Strings ........................................................................................... 142

5.8

Os comandos if-then-else e printf ............................................................ 145

Matrizes............................................................................................................................. 149
6.2

Matrizes e Comandos de Atribuio ......................................................................... 151

6.3

Aritmtica matricial ................................................................................................... 154

6.4

Construindo matrizes ................................................................................................ 158

6.5

Matrizes e Grficos .................................................................................................... 160

6.6

Grficos 3D ................................................................................................................ 163

6.7

Matrizes de Strings .................................................................................................... 165

6.8

Matrizes e Expresses Lgicas .................................................................................. 167

Loops ................................................................................................................................. 169


7.2

O comando while ................................................................................................... 171

7.3

Loop para o Clculo de Fatorial ................................................................................. 172

7.4

Loop para o Clculo da Soma dos Elementos de um Vetor ...................................... 173

7.5

Loop para encontrar o Menor Valor presente em um Vetor .................................... 174

7.6

Loop para encontrar o Mximo Divisor Comum usando o Algoritmo de Euclides ... 175

7.7

O comando for ........................................................................................................ 177

7.8

Gerao e Impresso de Tabelas .............................................................................. 178

7.9

Comandos Aninhados................................................................................................ 181

7.10

Gerao e Impresso de uma Tabuada de Multiplicao ......................................... 183

7.11

Arquivos .................................................................................................................... 184

7.12

Matrizes de Strings e Arquivos .................................................................................. 186

7.13

Matrizes Numricas e Arquivos ................................................................................ 187

7.14

Desenhando Mapas................................................................................................... 189

Funes ............................................................................................................................. 193


8.2

Funes e Reaproveitamento de Cdigo .................................................................. 195

8.3

Forma e Funcionamento ........................................................................................... 197

8.4

Funes, arquivos fonte e o Scilab ............................................................................ 199

8.5

Funes e Encapsulamento de Detalhes (e mais sobre arquivos) ............................ 200

Contedo
8.6

Funes e Desenvolvimento Top-down .................................................................... 203

8.7

Funes Recursivas ................................................................................................... 205

Algoritmos ......................................................................................................................... 208


9.2

Definio e Caractersticas ........................................................................................ 210

9.3

Fatorao................................................................................................................... 211

9.4

Melhorando a Fatorao ........................................................................................... 216

9.5

Pesquisa..................................................................................................................... 218

9.6

Pesquisa Seqencial .................................................................................................. 218

9.7

Pesquisa Binria ........................................................................................................ 219

10

Ordenao ..................................................................................................................... 222

10.2

Ordenao por Seleo ............................................................................................. 224

10.3

Intercalao (MergeSort) .......................................................................................... 229

10.4

Partio (QuickSort) .................................................................................................. 233

10.5

Dividir para Conquistar.............................................................................................. 239

10.6

Ordenao por Radical .............................................................................................. 239

11

Algoritmos Numricos ................................................................................................... 242

11.2

Integrao por Trapzios........................................................................................... 244

11.3

Bisseo ..................................................................................................................... 247

11.4

Srie de Taylor para exp(x) e Cancelamento Catastrfico ........................................ 252

12

Complexidade de Problemas......................................................................................... 256

12.2

Complexidade da Ordenao .................................................................................... 258

12.3

O Problema do Caixeiro Viajante .............................................................................. 261

12.4

Ordens de Complexidade e Reduo de Problemas ................................................. 267

12.5

P = NP? ...................................................................................................................... 270

12.6

Problemas indecidveis: O Problema da Correspondncia de Post .......................... 273

13

Prximos Passos ............................................................................................................ 280

ndice Remissivo ........................................................................................................................ 284


Referncias ................................................................................................................................ 287

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, ou simplesmente oferecidas como vdeo-aulas em cursos distncia ou
semi-presenciais;
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 pelo Moodle, e questes abertas (construo de circuitos e
programas) pelo plugin VPL1
Conjuntos de exerccios podem tambm ser disponibilizados no Moodle, permitindo
exames simulados 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 2 (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 o que so 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
1
2

VPL - Virtual Programming Lab, acessado 8 de outubro de 2013, http://vpl.dis.ulpgc.es/index.php.

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
aluno tem contato com bits, com operaes lgicas, com cdigos importantes como ASCII,
inteiros sem sinal e ponto flutuante. A composio de mdulos feita de forma visual, com
sadas alimentando entradas de forma evidente. Acumuladores so o primeiro contato com
loops, e somadores so um excelente exemplo de modularizao. A execuo sequencial de
instrues e instrues de desvios so tambm elementos que ajudam 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
MathWorks3, 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 Fortran4.
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 al5 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 continua6:
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

Mathworks, MathWorks - MATLAB and Simulink for Technical Computing, acessado 7 de


maro de 2011, http://www.mathworks.com/.
4
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.
5

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).
6

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

Prefcio
programming. On every customer contact I find new surprises. MATLAB satisfies all these
communities.
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 7. Links para esses
materiais podem ser encontrados no site 8 (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 Seminars9, 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.

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.
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

sciport-3.0.pdf, acessado 7 de maro de 2011, http://www.dca.ufrn.br/~pmotta/sciport3.0.pdf.


8
Scilab Consortium, Home - Scilab WebSite, acessado 7 de maro de 2011,
http://www.scilab.org/.
9
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
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 10, traduo do rabe
para latim do trabalho de al-Khwrizm.

10

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
Computer Science is no more about
computers than astronomy is about telescopes
Edsger Dijkstra

Mesmo se este for o seu primeiro contato com a programao de computadores, certo que
voc tem acesso a estes equipamentos e, portanto, tem uma boa idia do que so
computadores. Pois neste mdulo ns pretendemos apresentar computadores e seu objeto de
trabalho, a informao, do ponto de vista da Cincia da Computao, o que talvez te traga
algumas novidades. Ns veremos exemplos de computadores, comuns e incomuns, e alguns
fatos da histria de seu desenvolvimento. Vamos tambm introduzir a noo de informao
digital contraposta informao analgica, e ver como computadores lidam com esses dois
tipos de informao.
Veremos que computadores utilizam unidades de informao chamadas bits, capazes de
representar um dentre dois smbolos, comumente notados 0 e 1, e que, para representar mais
coisas, basta combinar conjuntos de bits. Apresentaremos tambm os principais componentes
de um computador, procurando tambm informar ordens de grandeza de capacidade e
desempenho.
Vamos tambm mostrar a organizao do curso e nossa forma de trabalho, incluindo a forma
de avaliao.

Computadores e Informao

13

Tpicos
1.
2.
3.
4.
5.
6.
7.
8.
9.

Computadores
Mdulos
Informao analgica e digital
Computadores e Informao
Converses A/D e D/A
Sensores e Atuadores
Memrias
Organizao do Curso
Forma de Trabalho

Objetivos
Esperamos que voc, ao final deste mdulo, seja capaz de:

Citar datas importantes da histria dos computadores


Nomear computadores no usuais: supercomputadores e computadores
embarcados
Explicar que, desde que tenham capacidade de armazenamento suficiente, todos os
computadores tm a mesma capacidade de transformao de informao
Citar ordens de grandeza de capacidades e velocidades de computadores, e ter
noo do ritmo de sua evoluo
Explicar o conceito de mdulo
Distinguir informao analgica de informao simblica (ou digital)
Explicar que computadores trabalham com dois smbolos apenas, que podem ser
armazenados na unidade bsica de informao, o bit
Calcular o nmero de combinaes possveis para n bits, e calcular quantos bits so
necessrios para representar m objetos
Enumerar os principais componentes de um computador
Descrever o contedo do curso e a forma de trabalho, e explicar a forma de
avaliao do aprendizado
Localizar o curso no Moodle da UFMG; submeter questionrios e tarefas no Moodle

Computadores e Informao

14

1.1 Computadores
Computadores eletrnicos programveis surgiram na dcada de 1940. Pouco mais de meio
sculo depois, 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 ensina e se aprende, como se faz comrcio, medicina, engenharia,
cincia, economia, como governar e como exercer a cidadania, e at mesmo como se namora.
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 198111

Este foi 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.
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.

11

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

Computadores e Informao

15

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 12

A cada seis meses uma lista com os maiores computadores do mundo publicada no site da
organizao Top500 13. Na lista de novembro de 2010, pela primeira vez o topo da lista foi
ocupado por um computador chins, o Tianhe-1A (Via Lctea-1A), com um desempenho de
12

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

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

Computadores e Informao

16

2,6 petaflops. Na lista de novembro de 2012 o primeiro lugar foi do computador Titan Cray
XK7, que atingiu 17 petaflops; em novembro de 2013 a China retomou o primeiro lugar, com o
Tianhe-2 que atinge 33 petaflops, lugar que continua ocupando at a lista de dezembro de
2015. 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-2 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 194614

Neste sentido o Eniac, construdo em 1946, e que conseguia fazer 385 multiplicaes em um
segundo15, era mais super que o Blue Gene ou que o Tianhe-2, pois era mil vezes mais potente
que seus predecessores.

14

Computer History Museum - Timeline of Computer History, acessado 16 de fevereiro de 2012,


http://www.computerhistory.org/timeline/?year=1946.
15
ENIAC - Wikipedia, the free encyclopedia, acessado 16 de fevereiro de 2012,
http://en.wikipedia.org/wiki/ENIAC.

Computadores e Informao

17

Figura 5: Evoluo do desempenho de computadores na lista Top500

guisa de comparao, o Tianhe-2 foi apenas 2 vezes mais rpido que seu predecessor no
topo da lista, fator que hoje considerado muito alto. A Figura 5 mostra a evoluo do
desempenho de computadores na lista top500.
Prever que os computadores sero cada vez mais rpidos fcil, mas prever como se dar sua
evoluo difcil, como bem ilustra o caso do MS-DOS16. 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.

16

Interview with Bill Gates, acessado 12 de fevereiro de 2016,


http://americanhistory.si.edu/comphist/gates.htm.

Computadores e Informao

18

Computadores transformam informao de


entrada em informao de sada. 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
17
de transformao de informao de forma
Figura 6: Alan Turing
efetiva, como uma composio de passos
garantidamente realizveis. Isso foi proposto pelo matemtico ingls Alan Turing em 1937 18,
alguns anos antes do funcionamento do primeiro computador eletrnico. Voltando ao Eniac,
ele no foi somente muito mais veloz que seus predecessores: foi o primeiro computador com
programa armazenado, capaz de resolver qualquer problema que uma mquina de Turing
resolve e, portanto, qualquer problema que os mais rpidos computadores atuais resolvem
em um tempo muito, muito maior, verdade.
Se as possibilidades de transformaes de informao so as mesmas para computadores
pequenos e grandes, rpidos e lentos, a velocidade com que a informao transformada
pode diferir por vrias ordens de grandeza. Em muitos casos, a velocidade que determina o
valor da informao obtida. Qualquer computador pessoal, com disponibilidade de
armazenamento externo suficiente, capaz de rodar um programa de previso meteorolgica
para saber como estar o tempo no dia seguinte, mas provvel 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.

Alan Turing - Wikipedia, the free encyclopedia, acessado 11 de maro de 2011,


http://en.wikipedia.org/wiki/Alan_Turing.
17

18

Alan M. Turing, On Computable Numbers, with an Application to the


Entscheidungsproblem, Proceedings of the London Mathematical Society s2-42, no 1 (1937):
23065.

Computadores e Informao

19

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

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 7.
Vemos ali que a correlao entre potncia computacional e competitividade econmica e
militar muito alta.

19

Home | TOP500 Supercomputing Sites.

Computadores e Informao

20

1.2 Mdulos
Mdulos so onipresentes na computao. Um modulo pode ser utilizado sabendo-se o que o
modulo faz, sem necessidade de compreenso de seu funcionamento interno. J um
construtor de um modulo, claro, precisa sim conhecer e bem seu funcionamento.

Figura 8: O Blue Gene e seus mdulos20, sub-mdulos, sub-sub-mdulos, ...

Vamos comear a ilustrar o uso de mdulos na computao com a estrutura do Blue Gene,
mostrada na Figura 8:

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.
Cada placa computacional tem duas pastilhas (chips) de circuitos integrados.
Cada chip abriga dois processadores, que so os circuitos que efetivamente realizam
clculos computacionais.

Na Figura 8 as sucessivas decomposies param por aqui mas, na verdade, um processador


ainda uma estrutura bastante complexa. Olhando para a imagem (Figura 9) 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.

20

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

21

Figura 9: Chip do processador Intel Core i7-980X21

Muitos componentes? Pois isso ainda pouco. Alm de suas partes visveis circuitos e
mecanismos um computador composto por software, nome coletivo para programas. O
software tambm organizado em mdulos, sub-mdulos, etc., em arranjos ainda mais
intrincados que todos os que vemos no hardware. Na Figura 10 ns vemos um esquema para a
organizao do sistema operacional Android22.

Figura 10: A estrutura do sistema operacional Android

21

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.
22
Android (operating system) - Wikipedia, the free encyclopedia, acessado 14 de fevereiro de 2016,
https://en.wikipedia.org/wiki/Android_(operating_system).

Computadores e Informao

22

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 11 propositalmente lembra uma
galxia. So centenas de milhes de computadores na Internet, todos interligados.

Figura 11: Uma visualizao da Internet pelo produzida pelo Projeto Opte 23

Todo esse imenso e complexo arranjo envolvendo satlites de telecomunicaes, cabos


submarinos, redes com e sem fios, fibras ticas, computadores, telefones celulares, circuitos
integrados, sistemas operacionais, programas, bancos de dados, 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, seus programas 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 utiliza, mas
normalmente no sabe como funcionam internamente os protocolos da Internet, e
provavelmente no tem a menor idia sobre a fsica de semicondutores dos chips.
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.

Figura 12: Um mdulo computacional transforma informao de entrada em informao de sada

23

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

Computadores e Informao

23

Mdulos computacionais transformam informao de entrada em informao de sada. Por


exemplo, um mdulo pode receber uma lista com nomes e salrios de funcionrios de uma
empresa, e produzir a informao da soma de todos os salrios.

Figura 13: Mdulos integrados com a sada de um alimentando a entrada de outro

Uma forma simples de produzir o efeito combinado de dois ou mais mdulos consiste em
colocar a sada de um mdulo alimentando a entrada de outro mdulo, como na Figura 13.

Figura 14: Mdulos combinados em um outro arranjo

Mdulos tambm podem ser combinados em arranjos mais intrincados, como na Figura 14.

Figura 15: Mdulos combinados vistos como um nico mdulo, com transparncia de funcionamento interno

Computadores e Informao

24

comum considerarmos a combinao de dois ou mais mdulos como um novo mdulo, que
pode ser visto com conhecimento de sua composio interna, como na Figura 15, ou somente
com conhecimento de sua funo composta, com detalhes invisveis como na Figura 16.

Figura 16: Arranjos de mdulos vistos como um nico mdulo, com encapsulamento de detalhes

Tcnicas de combinao de mdulos so um ponto central da Cincia da Computao. A cada


tipo de mdulo computacional que introduzirmos, a pergunta que sempre faremos : como
podemos combin-los para produzir efeitos compostos?

1.3 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.
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

Computadores e Informao

25

cada um de muitos pontos pequeninos que compem a imagem, nmeros que so smbolos,
ou seja, so informao digital.

Figura 17: Informao de imagem 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 cresa com a temperatura medida. Ns dizemos que a informao obtida por um
exame direto do termmetro uma informao analgica.

Ponto de ebulio
da gua

Corpo humano
Ponto de fuso
do gelo

Figura 18: 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).

Computadores e Informao

26

Ponto de ebulio
da gua

Corpo humano

Ponto de fuso
do gelo

Figura 19: Um termmetro com escala

Existem perdas nessa transformao. O mdico ir anotar o nmero correspondente ao


tracinho mais prximo extremidade da coluna, talvez arriscando 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 toda necessidade clnica.
Mas existe um grande ganho. A temperatura anotada informao simblica, que pode ser
comunicada por telefone, ou copiada em outro papel, ou digitada em um computador, e, por
ser um valor numrico, utilizada para, juntamente com outras medidas, obter mdias, grficos
ou em outros anlises.

Ponto de ebulio
da gua

50

Corpo humano
50

Ponto de fuso
do gelo

Figura 20: 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 20 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.

Computadores e Informao

27
Arbico
1
2
3
4
5
6
7

Romano
I
II
III
IV
V
VI
VII

Binrio
1
10
11
100
101
110
111

Figura 21: Tabela para converso de nmeros

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 Figura 21.

1.4 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.
Atuadores so impressoras, monitores de vdeo, placas de som, 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

Computadores e Informao

28

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 Figura 22 mostra os prefixos usados para designar potncias decimais e binrias de uso
corrente na computao.

Base para Prefixo


Prefixo

kilo
mega
giga
tera

Binrio

Mtrico

1024

1000

Smbolo

Expoente

1.024

1.000

1.048.576

1.000.000

1.073.741.824

1.000.000.000

1.099.511.627.776

1.000.000.000.000

Figura 22: Prefixos binrios e decimais

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
avaros 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
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.
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.5 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.

Computadores e Informao

29

Figura 23: Um microfone converte ondas de presso do ar em impulsos eltricos; um alto-falante converte
impulsos eltricos em ondas de presso24

Um exemplo destes dispositivos um microfone, que transforma sons em impulsos eltricos.


Como mostra o esquema na Figura 23, 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, e esse movimento gera ondas de presso no ar que constituem o som emitido.

Figura 24: Transmisso digital de udio

No arranjo mostrado na Figura 24, o sinal analgico produzido pelo microfone digitalizado e
transmitido por um canal digital. O sinal digital alimenta um conversor digital-analgico, que
produz pulsos eltricos que, espera-se, sejam uma reconstruo fiel do sinal analgico de
entrada, o que permitiria uma boa reproduo do som pelo alto falante.

24

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

Computadores e Informao

30

Figura 25: Um segundo de um sinal analgico

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

22=4

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

A Figura 26 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 27.
Tempo(s)

Sinal(V)

0.00

00 (0)

0.33

10 (2)

0.66

10 (2)

1.00

00 (0)

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

Computadores e Informao

31

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 28

Figura 28: 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 29.

Figura 29: 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 30.

Figura 30: 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 31 mostra as amostras

Computadores e Informao

32

obtidas pelo processo de digitalizao, e a Figura 32 sua reconstruo por interpolao linear e
spline.

22=4

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

Figura 32: 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.

Computadores e Informao

33

26=64

Figura 33: 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 33.

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

Na reconstruo do sinal, como mostra a Figura 34, 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

Computadores e Informao

34

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.6 Sensores e atuadores


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 35: Barbara Blackburn, recordista mundial de velocidade de digitao 25, 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 35).
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 36: 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.

25

Barbara Blackburn, the Worlds Fastest Typist, acessado 15 de setembro de 2012,


http://rcranger.mysite.syr.edu/famhist/blackburn.htm.

Computadores e Informao

35

Figura 37: 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 38: 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 38.

1.7 Memrias
Memrias so usadas por computadores como ns usamos papel e lpis: 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 trans formaes 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

Computadores e Informao

36

ncleos de ferrite, com o registro da informao feito por polarizaes magnticas no


volteis.

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

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

26

Magnetic-core memory - Wikipedia, the free encyclopedia, acessado 12 de maro de 2011,


http://en.wikipedia.org/wiki/Magnetic_core_memory.

Computadores e Informao

37

Figura 41: 8 bytes x 8 gigabytes

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 42: 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

38

Figura 43: Armazenamento tercirio com uma grande coleo de fitas magnticas manipuladas por um brao
robtico27

Como j dissemos, memrias cumprem a mesma funo que um papel para ns humanos:
serve para anotar informaes para recuperao posterior. Na Figura 44 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.

27

NCARs MSS exceeds 2 petabytes, acessado 12 de agosto de 2011,


http://www.cisl.ucar.edu/news/04/fotoweek/0729.mss2pb.html.

Computadores e Informao

39

Figura 44: Escrevendo zeros e uns em meio magntico28

1.8 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.

28

File:MagneticMedia.png - Wikipedia, the free encyclopedia, acessado 12 de agosto de 2011,


http://en.wikipedia.org/wiki/File:MagneticMedia.png.

Computadores e Informao

40

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

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 1 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 46: 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, por ser
carregado em uma memria, 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

Computadores e Informao

41

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.
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.
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 47).

Figura 47: 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

42

Funesutilizadas

// Programa da Onda
getf("Minimo.sci");
Leituradoarquivo
getf("Maximo.sci");
arq = xgetfile();
Geraodogrfico
Onda = fscanfMat(arq);
Sada
plot2d(Onda);
printf("Min = %5.2f, Max = %5.2f",...
Minimo(Onda), Maximo(Onda));

Figura 48: 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 48 mostra um programa Scilab que faz isso, utilizando dois mdulos, as funes
Maximo e Minimo, mostradas na Figura 49.

Figura 49: 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 50, e a sada Min = -0.86, Max = 0.36
mostrada na console do Scilab.

Computadores e Informao

43

Figura 50: 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 51: 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 51, 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 que, pela aplicao de uma sequncia de operaes, produza 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

Computadores e Informao

44

um vetor de 2 elementos, sabemos encontrar o mnimo em um vetor com 3 elementos.


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.

24.

50.

42.

28.

8.

62.

34.

70.

52.];

A = [39.

24.

50.

42.

28.

8.

62.

34.

70.

52.];

A = [39.

24.

50.

42.

28.

8.

62.

34.

70.

52.];

A = [39.

24.

50.

42.

28.

8.

62.

34.

70.

52.];

A = [39.

24.

50.

42.

28.

8.

62.

34.

70.

52.];

A = [39.

24.

50.

42.

28.

8.

62.

34.

70.

52.];

Figura 52: 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 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.

Computadores e Informao

45

Sntese
Neste mdulo vimos que computadores transformam informao. Vimos exemplos de
computadores, grandes e pequenos, e observamos que, apesar das enormes diferenas,
todos tm a mesma capacidade de transformao de informao. Isso posto, vimos
tambm que a velocidade dos computadores pode diferir entre modelos por diversas
ordens de grandeza, e que a velocidade determinante para o valor da transformao
de informao.
Tivemos um primeiro contato com a noo de mdulo, um componente que pode ser
utilizado sabendo-se somente qual a sua funo, sem necessariamente saber como
essa funo executada. Vimos que computadores trabalham com informao digital e
analgica, mas que no tratamento da informao digital que o poderio dos
computadores se revela.
Vimos que, por razes de confiabilidade, computadores utilizam somente dois smbolos
bsicos, notados 0 e 1, e que um bit a unidade de informao capaz de armazenar um
destes smbolos. O uso de somente dois smbolos no uma restrio, pois combinando
bits, temos 2 possveis representaes. Apresentamos tambm os principais
componentes de um computador: processador, memria, e perifricos de entrada e
sada.
Vimos tambm a organizao do curso e a forma de trabalho, incluindo os critrios para
avaliao de aprendizado. No prximo mdulo ns veremos elementos bsicos de
transformao de informao e formas de combin-los para obter somas, comparaes
e direcionamento de dados.

Circuitos Combinatrios

46

2 Circuitos Combinatrios
The design of the following treatise is to investigate the
fundamental laws of those operations of the mind by which
reasoning is performed; to give expression to them in the symbolical
language of a Calculus, and upon this foundation to establish the
science of Logic and construct its method.
George Boole, 1854, An Investigation of the Laws of Thought, Capitulo I

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.

Circuitos Combinatrios

47

Tpicos
1.
2.
3.
4.
5.
6.
7.

Bits e Cdigos
lgebra de Boole
Portas Lgicas e Transistores
Soma de binrios de 1 bit
Soma de binrios de n bits
Modularizao e Sntese Automtica de Circuitos no Logisim
Comparadores, Multiplexadores e Demultiplexadores

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
1. Explicar que bits exigem cdigos para ter significado
2. Defender a importncia da existncia de cdigos de larga aceitao, e ser capaz de
citar alguns deles
3. Determinar o significado de um conjunto de bits para um cdigo conhecido
4. Descrever as operaes bsicas da lgebra de Boole e saber como se combinam em
expresses lgicas
5. Combinar operaes bsicas da lgebra de Boole em expresses lgicas
6. Construir um circuito lgico a partir de uma expresso lgica, e extrair uma
expresso lgica a partir de um circuito
7. Descrever como transistores podem ser utilizados para a realizao das operaes
da lgebra de Boole
8. Definir uma Tabela da Verdade
9. Sintetizar um circuito combinatrio a partir de sua Tabela da Verdade
10. Explicar um circuito de soma em cascata como uma realizao do algoritmo de
soma
11. Utilizar o Logisim para sntese automtica de circuitos a partir de sua Tabela da
Verdade
12. Descrever circuitos comparadores, multiplexadores e demultiplexadores

Circuitos Combinatrios

48

2.2 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 e 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 53: Exemplos de codificao ASCII

A Figura 53 mostra partes do cdigo ASCII, cuja primeira verso foi proposta em 196329. O
cdigo foi projetado para a representao de caracteres como A, a, (, +, 1, 2, etc.,
para o espao em branco (sim, o espao tambm exige uma representao), e para os
chamados caracteres de controle. 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.

29

ASCII - Wikipedia, the free encyclopedia, acessado 18 de agosto de 2011,


http://en.wikipedia.org/wiki/ASCII.

Circuitos Combinatrios

49

Figura 54: 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 197230

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 Unicode31, 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
por um nico byte tm a mesma representao em UTF-8 e em ASCII, uma compatibilidade
essencial para manter funcionando programas que contavam com codificao ASCII.
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 de informao
numrica produzida em 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

30

Ken&Den picture, acessado 24 de setembro de 2012, http://cm.belllabs.com/cm/cs/who/dmr/picture.html.


31
Unicode - Wikipedia, the free encyclopedia, acessado 19 de agosto de 2011,
http://en.wikipedia.org/wiki/Unicode.

Circuitos Combinatrios

50

compactos e que, como veremos, permitem a realizao de operaes de soma por circuitos
mais simples, mais rpidos e mais baratos.

10

16

32

64

128

256

512

1024

Figura 55: 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 56: 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 55, 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
55, 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

Figura 57: 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

51

Figura 58: 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 (poderia ser
o contrrio). 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 59. 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 59: 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 60
mostra a codificao em 3 bits dos inteiros entre -4 e 3 usando complemento de 2.

Circuitos Combinatrios

52

b2
0
0
0
0
1
1
1
1

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

0
1
0
1
0
1
0
1

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

Figura 60: 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 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

53

Significando
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10

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

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

159
32

1,65625

7113539584

Expoente

Valor

Figura 61: Um nmero em ponto flutuante com 32 bits

A Figura 61 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 32 tem um bom resumo do padro
IEEE 754.

2.3 lgebra de Boole


Em 1854 o matemtico ingls George Boole props uma lgebra para o clculo da validade de
expresses formadas por proposies lgicas33. Quase um sculo depois, em 1937, Claude
Shannon34, ento com 21 anos, em sua dissertao de mestrado defendida no MIT,
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.

32

Steve Hollasch, IEEE Standard 754 Floating-Point, acessado 7 de maro de 2011,


http://steve.hollasch.net/cgindex/coding/ieeefloat.html.
33

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.
34
Claude Shannon - Wikipedia, the free encyclopedia, acessado 19 de agosto de 2011,
http://en.wikipedia.org/wiki/Claude_Shannon.

Circuitos Combinatrios

54

Figura 62: George Boole, 1820-189835, e Claude Shannon, 1916-200136

As operaes fundamentais da lgebra de Boole so NO, E e OU, mais conhecidas pelas


palavras em ingls NOT, AND e OR. 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 63: Definio das operaes NOT, OR e AND

A Figura 63 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 dois 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:

35

denota NOT
+ denota OR
. ou denota AND

George Boole - Wikipedia, the free encyclopedia, acessado 23 de fevereiro de 2012,


http://en.wikipedia.org/wiki/George_Boole.
36
Claude Shannon - Wikipedia, the free encyclopedia.

Circuitos Combinatrios

55

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 64: Portas lgicas, entradas e sadas em um diagrama de circuito

Circuitos digitais que implementam operaes booleanas so conhecidos como portas lgicas.
A Figura 64 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 65. A simplificao de expresses booleanas portanto uma rea da mais alta
importncia, mas que foge do nosso escopo.

Circuitos Combinatrios

56

Figura 65: 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.4 Portas Lgicas e Transistores

Figura 66: Lei de Moore: o nmero de transistores por rea dobra a cada dois anos 37

37

Moores law - Wikipedia, the free encyclopedia, acessado 3 de maro de 2013,


http://en.wikipedia.org/wiki/Moore_Law.

Circuitos Combinatrios

57

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 cm 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).
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. Uma tabela com estas funes pode ser vista na Figura 67.

a AND b

a NAND b

a OR b

a NOR b

0
0
1
1

0
1
0
1

0
0
0
1

1
1
1
0

0
1
1
1

1
0
0
0

Figura 67: Tabela das funes AND, NAND, OR e NOR

A Figura 68 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.

Figura 68: Smbolos para portas NAND e NOR em diagramas lgicos

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.

Circuitos Combinatrios

58

Voltagem
de Controle

Voltagem
naEntrada

Voltagem
na Sada

Figura 69: 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:

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.

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 70, 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 70: 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.

Circuitos Combinatrios

59

Fonte V= 5
(voltagem alta)

a
0

a
1

Terra V= 0
(voltagem baixa)

Figura 71: 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.
Fonte

0 (a + b)
a
1

b
0
Terra

Figura 72: Uma porta NOR construda com dois transistores

Uma porta NOR construda com o arranjo de transistores mostrado na Figura 72; 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 73: Uma porta NAND implantada com transistores

Circuitos Combinatrios

60

Uma porta NAND construda de forma similar, mas com os transistores ligados em srie,
como mostra a Figura 73. 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.

Fonte

Fonte

a.b
0
a
1

Terra

b
0

NAND

NOT

Figura 74: Porta AND com 3 transistores

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

2.5 Introduo ao Logisim


O Logisim38 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 75, 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.

38

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

Circuitos Combinatrios

61

Componentes de
uso frequente

rea de desenho
de circuitos
Cardpio de
portas e outros
circuitos

Figura 75: 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 76. 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

62

Porta AND

Componente
selecionado

Atributos do
componente
selecionado

Figura 76: Duas portas AND

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

NOT

OR

Figura 77: Acrescentando portas NOT e OR

O prximo passo a colocao de entradas e sadas, que so colocadas usando os cones em


destaque na Figura 78.

Circuitos Combinatrios

Entrada

63

Sada

Figura 78: Acrescentando entradas e sadas

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

Seleo

Figura 79: Acrescentando o cabeamento

Circuitos Combinatrios

64

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 80 que implementa o Ou Exclusivo.

Contato

Cruzamento
sem contato

Figura 80: Circuito OU Exclusivo

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

Texto

Rtulo

Figura 81: Acrescentando textos a um circuito

Circuitos Combinatrios

65

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 81.

Ferramenta
de simulao

Figura 82: Ferramenta de simulao

Para testar o seu circuito, use a ferramenta de simulao a mozinha em destaque na Figura
82. 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 83.
A
0
0
1
1

B
0
1
0
1

a XOR b

Figura 83: 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 84.

Circuitos Combinatrios

66

Figura 84: 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.6 Soma de duas parcelas de 1 bit

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

Ns vimos como circuitos lgicos implementam expresses lgicas, com um mapeamento


direto. Por exemplo, a Figura 85 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

67

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 86 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 86: 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 87 mostra a tabela da verdade para a
soma de duas variveis de 1 bit.

Entradas

Todos os
valores
possveis para
as entradas

Sadas:
2 funes
lgicas das
mesmas
variveis

Resultados da
soma em
binrio sem
sinal

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

Circuitos Combinatrios

68

Nas colunas dessa tabela ns temos:

duas variveis de entrada, e ;


duas funes de sada, 1 e 0; cada funo corresponde a um dgito binrio do
resultado;

Temos tambm uma linha na tabela para cada uma das combinaes possveis de valores para
as variveis de entrada; em cada linha temos tambm 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.3.
Dada uma expresso lgica, ns podemos construir sua tabela da verdade efetuando as
operaes da expresso. A Figura 88 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 88: 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 89 equivalente expresso (, ) = + .

f(x,y)

0
0

0
1

1
0

1
1

0
1

0
1

Figura 89: 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

69

f(x,y)

xy + xy

Figura 90: Cobertura dos 1s de uma funo booleana

Na Figura 90, (, ) = 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 91: 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 91 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 92
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

70

ab
ab

ab

Figura 92: 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.7 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, criado, ou pelo menos difundido no

Circuitos Combinatrios

71

Ocidente, por Muammad ibn Ms al-Khwrizm, matemtico rabe39 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
rpido: 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 93).

Vai-um
a
b
a+b

1
2
4
7

1
7 7 6
7 9 1
5 6 7

Figura 93: 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 94 mostra o processo do clculo de 1011101+1001110.
Vai-Um
1

Parcelas

Soma

Figura 94: 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.

39

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

Circuitos Combinatrios

72

vai-um
soma

SC

vem-um

a
b

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

Este mdulo, esquematizado na Figura 95, 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 96: Arranjo em cascata de mdulos para um somador de 4 bits

A Figura 96 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

73

soma = abv + abv + abv + abv


a

vem-um

soma

vai-um

vai-um = abv + abv + abv + abv

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

A Figura 97 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 98: Circuito Soma Completa, construdo diretamente a partir das expresses obtidas da tabela da verdade

A Figura 98 mostra um circuito de soma completa construdo com a utilizao destas


expresses lgicas.

Circuitos Combinatrios

74

Figura 99 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 96. A Figura 99 mostra um somador de 4 bits obtido com este
desenho.

2.8 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 100: Abrindo a janela de anlise combinacional do Logisim

Abra o Logisim, e siga o menu Janela/Anlise Combinacional, como mostrado na Figura 100.
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 101.

Circuitos Combinatrios

75

Figura 101: Definindo no Logisim as entradas do circuito

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

Figura 102: 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 97.

Circuitos Combinatrios

76

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

A Figura 103 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 104: 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 104.

Circuitos Combinatrios

77

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

Aperte o boto OK e... como mostra a Figura 105, nosso circuito de soma completa est
pronto! Mas est um pouco diferente do circuito que j construmos, mostrado na Figura 98.
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 105. Para isto d um duplo clique sobre o
sub-circuito 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

78

Figura 106: 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 106, 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

79

Figura 107: 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 108: Somador de 4 bits completo, utilizando sub-circuitos de soma completa

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

Circuitos Combinatrios

80

2.9 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 109: 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

Upper Right

Lower Left
Lower Right

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

A Figura 110 mostra os rtulos dos pinos de entrada de uma lmpada de 7 segmentos, e na
Figura 111 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

4 bits de
entrada

81

Circuito que
queremos

Figura 111: 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 112.

Figura 112: 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 113. 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 111.

Circuitos Combinatrios

82

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

2.10 Comparao de binrios sem sinal


a

b
Comparador

a<b

a=b

a>b

Figura 114: Entradas e sadas de um circuito comparador

Vimos na seo 2.6 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 114.
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

83

aMaior
abIguais
bMaior

aMaior
abIguais
bMaior

aMaior
abIguais
bMaior

a
b

1
1

1
1

1
1

1
0

1
1

0
1

0
1

0
0

0
1
0

0
1
0

0
1
0

0
1
0

1
0
0

1
0
0

1
0
0

1
0
0

1
0
0

a
b

0
1

1
1

1
1

1
0

1
1

0
1

0
1

0
0

0
1
0

0
0
1

0
0
1

0
0
1

0
0
1

0
0
1

0
0
1

0
0
1

0
0
1

a
b

1
1

1
1

1
1

0
0

1
1

0
0

1
1

0
0

0
1
0

0
1
0

0
1
0

0
1
0

0
1
0

0
1
0

0
1
0

0
1
0

0
1
0

Figura 115: 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 115 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
Amaior

b
aMaior
bMaior

Mdulo
Comparador
de 1 bit

Bmaior
ABiguais

abIguais

Vm do comparador
esquerda

Vo para o
comparador direita

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

Vemos na Figura 116 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

84

j feita com bits mais significativos que o bit em questo vm as entradas aMaior, bMaior e
abIguais. A Figura 117 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 117: 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 118 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

85

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 118: Tabela da verdade para um comparador de 1 bit

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

Figura 119: Circuito comparador de 1 bit

Circuitos Combinatrios

86

2.11 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 120: Multiplexadores (MUX) e Demultiplexadores (DMX)

Como mostra a Figura 120,

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 121: Tabela da verdade para um multiplexador de 1 bit

A Figura 121 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

87

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

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

Na Figura 122 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 123: 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 124.

O binrio a1a0
designa qual
entrada fica
ligada sada

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

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

Circuitos Combinatrios

88

Figura 125: 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 126.

DMX
1 bit
DMX
1 bit
DMX
1 bit

Figura 126: 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 127.

Entrada
codificada
em binrio

Constante
1

Sada
decodificada

Figura 127: Decodificador de 3 bits

Circuitos Combinatrios

89

Sntese
Neste mdulo vimos circuitos combinatrios circuitos cuja sada exclusivamente
funo da entrada aplicada no momento. Circuitos combinatrios, como todo artefato
computacional, transformam bits contendo informao de entrada em bits com
informao de sada. Para dar significado a estes conjuntos de bits, precisamos de uma
conveno um cdigo para dar-lhes uma interpretao. O projetista de um circuito
sequencial pode dar aos bits de entrada e de sada a interpretao que desejar, mas o
uso de cdigos cdigos de larga aceitao, como ASCII, binrios sem sinal, ou ponto
flutuante, frequentemente a nica opo vivel por razes de interoperabilidade ou
de aproveitamento de hardware especfico.
Ns vimos que as operaes fundamentais feitas sobre bits so as operaes da lgebra
de Boole, NOT, AND e OR. Vimos tambm que com poucos transistores possvel
implementar portas lgicas, que so circuitos que realizam estas operaes, e que
podem ser contrudos em semi-condutores de forma extremamente densa e eficaz.
Portas lgicas podem ser combinadas de forma a construir circuitos que correspondem
a expresses lgicas expresses formadas por variveis, NOT, AND e OR, e parnteses.
Uma funo lgica, ou funo booleana, uma funo cujos argumentos so variveis
lgicas, e cuja sada tambm um valor lgico. Uma funo lgica pode ser definida por
uma tabela da verdade, que uma tabela definindo o valor da funo para cada possvel
combinao dos valores de seus argumentos.
Ns vimos tambm que possvel derivar uma expresso lgica correspondente a uma
funo a partir de sua tabela da verdade, pelo mtodo de cobertura dos 1s. Com isso
ns fomos capazes de construir circuitos de meia-soma e de soma completa, para
realizar a soma de duas parcelas de um nico bit codificado como binrio sem sinal. Ns
mostramos que possvel ligar em cascata circuitos de soma completa (que recebem e
produzem bits de vai-um) para conseguir somar parcelas de mais de um bit.
Mostramos tambm outros circuitos sequenciais importantes, como comparadores,
multiplexadores e demultiplexadores.
No prximo mdulo ns veremos circuitos sequenciais, que contm elementos de
memria.

Circuitos Sequenciais

90

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,
como resultados parciais de somas. 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.

Circuitos Sequenciais

Tpicos
1.
2.
3.
4.
5.
6.

Flip-flops e registradores
Barramentos e controle de Fluxo de dados
Memrias
Acumuladores e loops
Uma calculadora
Clocks

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
13. Explicar porque um circuito sequencial pode ser muito mais poderoso que um
circuito combinatrio
14. Descrever elementos bsicos de memria: flip-flops e registradores
15. Descrever barramentos
16. Explicar conflitos em barramentos e o uso de buffers controlados
17. Criar sequncias de sinais de controle necessrios para escrita e leitura de palavras
em uma memria RAM do Logisim
18. Explicar a estrutura de conexo com realimentao de um registrador acumulador
19. Criar sequncias de sinais de controle para a realizao de operaes aritmticas
compostas, com armazenamento de resultados intermedirios, usando uma
calculadora
20. Descrever clocks
21. Explicar como o sinal de um clock pode ser aproveitado para a emisso de
sequncias mais elaboradas de sinais.

91

Circuitos Sequenciais

92

3.2 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 128: 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 128
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.
Pino Enable: uma entrada auxiliar que serve para habilitar ou inibir o
comportamento do flip-flop.

Circuitos Sequenciais

93
7

Clock

D
2

Q
0

-1
1

10

11

12

13

Tempo
Figura 129: 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 129 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 130: Um registrador de 4 bits formado por flip-flops tipo D

Flip-flops podem ser agrupados formando registradores, que so conjuntos de flip-flops com
alguma misso em comum. A Figura 130 mostra um registrador de 4 bits, cuja funo similar

Circuitos Sequenciais

94

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 131: 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

95

Figura 132: Dois diagramas de um mesmo circuito. No circuito de cima, fios e registradores tm 1 bit de largura;
no de baixo, 4 bits

Na Figura 132 ns vemos dois diagramas para um mesmo circuito com dois registradores de 4
bits conectados. O diagrama 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 131. 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 133: 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 133.

Circuitos Sequenciais

96

3.3 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 134: 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

97

Passo
1
2
3
4
5

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

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

Passo
1
2
3
4
5

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

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

Passo
1
2
3
4

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 135 : Exemplos de fluxos de dados realizveis pelo circuito da Figura 134.

O circuito da Figura 134 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 135 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.4 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

98

Entrada e
tambm sada
de dados

Memory
Address
Register

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

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

A Figura 136 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 136, 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.
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
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
8
Input = 9
Colocar 9 (em binrio, 1001) na entrada Input
9
In_Clk = 1
Copiar no registrador In a entrada Input
10
In_Clk = 0
Zerar o clock do registrador In
11
In_Bus = 1
Colocar o valor de In no barramento
12
RAM_Clk = 1 Copiar o valor do barramento no endereo A da RAM
13
RAM_Clk = 0 Zerar o clock da memria
14
In_Bus = 0
Liberar o barramento
Figura 137: Um fluxo de dados realizvel pelo circuito da Figura 136

Passo
1
2
3
4

Sinal
Input = 15
In_Clk = 1
In_Clk = 0
In_Bus = 1

Exemplos de fluxos de dados realizveis com o circuito da Figura 136 so mostrados na Figura
137 e na Figura 138.

Circuitos Sequenciais

99

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 138: Outro exemplo de fluxo de dados realizvel com o circuito da Figura 136

3.5 Acumuladores e Loops

Registrador
Acumulador

Circuito Soma
(combinatrio)

Figura 139: Um registrador acumulador

Um registrador pode ser usado como um acumulador, como mostrado na Figura 139. 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

100

5
6

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

In = 7

Passo
1
2
3
4

8
9
10
11
12
13
14
15
16
17

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

Figura 140: Exemplo de fluxo de dados realizvel pelo circuito da Figura 139

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

3.6 Uma Calculadora

Figura 141: Uma calculadora

Circuitos Sequenciais

101

A Figura 141 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 ULA capaz de realizar
somas, subtraes, multiplicaes, divises e comparaes entre suas duas entradas.

Determina qual das operaes


fornece o resultado

Figura 142: A ULA (Unidade Lgico-Aritmtica) da Calculadora

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 > ACC, Bus = ACC e Bus < ACC.

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 141 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 multiplicar 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. Multiplicar o contedo do acumulador pelo contedo da posio 2 da RAM
3. Armazenar o contedo do acumulador na posio 3 da RAM.
A Figura 143 mostra uma tabela com uma sequncia de aes a serem executadas por um
operador Logisim para obter este efeito. Essas aes so sinais de controle a serem aplicados

Circuitos Sequenciais

102

calculadora ou entradas de valores literais necessrios para essa computao. Na notao


utilizada, 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.

Passo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

Ao
ACC_Clr = 1
ACC_Clr = 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
Input=2
In_Clk=1
In_Clk=0
In_Bus = 1
MAR_Clk = 1
MAR_Clk = 0
In_Bus = 0
RAM_Bus = 1
Operao=10
ACC_Clk = 1
ACC_Clk=0
RAM_Bus = 0
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

Efeito

Efeito Acumulado

Zera o acumulador
Coloca 1 no registrador In
Coloca o contedo de In no barramento
Copia o barramento no registrador MAR

Transfere o contedo da palavra da RAM


de endereo 1 para o Acumulador

Libera o barramento
Coloca o contedo da palavra da RAM de endereo MAR no barramento
Copia o barramento no registrador ACC
Libera o barramento
Coloca 2 (10 em binrio) no registrador In
Coloca o contedo de In no barramento
Copia o barramento no registrador MAR
Libera o barramento
Coloca o contedo da palavra da RAM de endereo MAR no barramento
ULA passa a multiplicar

Multiplica o acumulador pelo contedo


da palavra da RAM de endereo 2

Copia a sada da ULA no registrador ACC


Libera o barramento
Coloca 3 (11 em binrio) no registrador In
Coloca o contedo de In no barramento
Copia o barramento no registrador MAR
Libera o barramento
Coloca o contedo de ACC no barramento

Transfere o contedo do acumulador


para a palavra da RAM de endereo 3

Copia o valor no barramento para a palavra da RAM de endereo MAR


Libera o barramento

Figura 143: Um programa a ser seguido por um operador da calculadora

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 valores j conhecidos no momento
da programao de valores literais, ou simplesmente literais.

3.7 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 144.

Circuitos Sequenciais

103

Figura 144: 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 145: Um registrador circular

A Figura 145 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

104

t2

t1
t0

Clock
Reset

Figura 146: Carta de tempo para o registrador circular da Figura 145

A Figura 146 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.

Circuitos Sequenciais

105

Sntese
Neste mdulo vimos circuitos sequenciais circuitos cuja sada depende no somente
dos valores aplicados s suas entradas, mas tambm de valores guardados em suas
memrias. O circuito sequencial mais simples o flip-flop, elemento capaz de
armazenar um bit. O valor armazenado no flip-flop determinado pelo valor de sua
entrada, amostrado em um instante preciso no tempo: a subida de 0 para 1 de sua
entrada Clock.
Registradores so conjuntos de flip-flops com uma misso comum. Um registrador de
dados tem um nico sinal alimentando as entradas de Clock de seus flip-flops.
Registradores so geralmente interconectados por barramentos, que so cabos capazes
de transportar vrios bits em paralelo, e cujo acesso deve ser controlado para evitar
conflitos.
Um registrador acumulador um registrador de dados que trabalha em conjunto com
um circuito aritmtico, que faz somas, subtraes, divises e multiplicaes. A entrada
do registrador alimentada pela sada do circuito aritmtico. Uma das entradas do
circuito aritmtico (um de seus operandos) alimentada pelo barramento, enquanto a
outra entrada alimentada pelo registrador de dados. Isso forma um ciclo que permite
a realizao de um nmero arbitrrio de operaes aritmticas, com resultados parciais
guardados no acumulador.
Uma memria guarda bits em conjuntos de tamanho fixo, chamados palavras. A cada
palavra corresponde um endereo. Operaes de leitura e escrita so feitas em uma
nica palavra, designada por seu endereo. A largura de dados de uma memria o
nmero de bits em cada palavra. Uma memria com bits de endereo tem no mximo
2 palavras.
Combinando todos esses componentes, ns vimos um circuito que funciona como uma
calculadora, e que necessita da interveno do operador do Logisim para realizar
computaes arbitrariamente complexas. No prximo mdulo ns veremos como
transformar essa calculadora em um processador, que um circuito que realiza
computaes determinadas por um programa.

4 - Processadores

106

4 Processadores
No nosso estudo de circuitos lgicos, vimos como as operaes NOT, AND e OR podem ser
combinadas para produzir circuitos que executam operaes lgicas, somas ou comparaes.
Vimos tambm como a adio de componentes com memria traz um aumento de poderio
computacional, com a possibilidade de armazenamento de resultados intermedirios e do
sequenciamento no tempo de um nmero arbitrrio de operaes. Pois veremos neste
mdulo um outro salto de poderio, talvez mais significativo. Veremos como construir
processadores, que so circuitos lgicos que fazem transformaes de informao
determinadas no apenas por sua construo, mas por programas armazenados em uma
memria.

4 - Processadores

Tpicos
1.
2.
3.
4.
5.
6.

Revisitando a calculadora
Programa armazenado
Um primeiro processador
Processador com instrues de desvio
Processador com instrues de desvio condicional
CPUs reais: instrues e programao em Assembler

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
22. Explicar a noo de programa, como instrues a serem seguidas por humanos
23. Explicar como seguir um programa significa gerar uma sequncia de sinais de
controle adequada ao objetivo do programa
24. Explicar como um programa pode ser codificado em bits, armazenado em uma
memria, e ser seguido por um mecanismo de varredura desta memria movido
por um clock
25. Construir um programa em linguagem de mquina para um processador simples
26. Explicar e utilizar instrues de desvio condicional e incondicional

107

4 - Processadores

108

4.2 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.

Figura 147: Codificao de sinais de controle em micro-instrues

A Figura 147 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
Figura 141. 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

4 - Processadores

109

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

Sinais

A cada subida do
clock, o valor no
PC incrementado

Memria de
Programa

Figura 148: 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 148 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

110

Figura 149: Uma caixa de msica 40; 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
149 (no deixe de ver e ouvir o vdeo no YouTube; muito bom), onde o cilindro tem o papel
de uma memria onde est gravado um programa..

Soma 1

Registrador

Figura 150: Um contador de programa simples

A Figura 150 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.

40

bigbluesky2002, YouTube - Swiss Antique Music Box, acessado 1 de abril de 2011,


http://www.youtube.com/watch?v=-tzWt1X3oOg&p=66A384A130B0DCE4.

4 - Processadores

111

4.3 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 Literal no
Barramento
Bit 23 indica
se a palavra
codifica um
literal

Literal nos 16 bits


menos significativos
=2

Figura 151: Codificao de operandos em micro-instrues

A Figura 151 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

112

Figura 152: 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 152 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.

4 - Processadores

113

Calculadora

Controle

Figura 153: A CPU-0 como uma composio da calculadora com uma unidade de controle

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.

Sada de
Literal

fornece tempos para


atualizaes:
t0: PC
t1: Sinais ou Literal

Micro-instruo
corrente

Sada de
Sinais

Acompanhamento visual

Figura 154: Unidade de controle da CPU-0

A Figura 154 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 que so fornecidos para a


CPU pelas sadas de mesmo nome;

4 - Processadores

114

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 145, e que ao longo
do tempo fornece os sinais t0 e t1 conforme mostrado na Figura 146;
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 Literal, 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.

Micro-instruo
23

22 21 20 19 18 17 16 15 14 13 12 11 10 9

Efeito

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

DR_Clk
Literal_Bus
In_Bus
In_Clk
MAR_Clk
RAM_Bus
RAM_Clk
DR_Bus
Oper1
Oper0
Out_Clk
Compare_Clk
ACC_Bus
ACC_Clk
ACC_Clear

Literal?

Endereo

Sinais

1
1
1

1
1
1

1
1

1
1
1

1
1
1
1

0
1
1

1
1
1

1
1

1
1

Da microAcumulado
instruo

1 ACC = 0
1 Literal = 1
Bus = Literal
MAR = Bus
Bus = RAM
ACC = ACC + Bus
Literal = 2
Bus = Literal
MAR = Bus
Bus = RAM
Oper = 10 (x)
ACC = ACC x Bus
1 Literal = 3
Bus = Literal
MAR = Bus
Bus = ACC
RAM = Bus

Carrega no acumulador
o contedo da posio 1
da RAM

Multiplica o acumulador
pelo contedo da
posio 2 da RAM

Armazena o contedo
do acumulador na
posio 3 da RAM

Figura 155: Construindo um programa para a CPU-0

Para programar a CPU-0 ns podemos usar uma tabela como a da Figura 155, 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 155 corresponde

4 - Processadores

115

exatamente aos sinais de controle e entradas de operandos mostrados na Figura 143. 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 bootstrapping. 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.

Figura 156: Painel de um PDP11/70, de 197541

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 156, 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.

41

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

116

Figura 157: Arquivo com mapa de memria usado pelo Logisim

Neste curso 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 arquivo um mapa da memria (para ter acesso a essas operaes, clique com o boto
direito do mouse sobre a memria). A Figura 157 mostra o formato de um arquivo com a
codificao em hexadecimal do programa da Figura 155 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.4 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 158.

Soma de 2 parcelas

Soma de 5 parcelas
Sinais

1
1

1
1
1

1
1
1

1
1

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

Operando?

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?

Sinais

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 158: 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

4 - Processadores

117

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.

Bit 23: Literal?


Bit 22: Desvio?

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

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

A Figura 159 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.

4 - Processadores

Bit 22:
deciso de desvio

118

Endereo
para desvio

Figura 160: 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

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 160 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.

4 - Processadores

Endereo
de Desvio

119

Deciso sobre
o prximo
valor do PC

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

A Figura 161 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 162: Um programa para a CPU-1

Na Figura 162 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.5 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

4 - Processadores

120

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 163: Codificao de micro-instrues de desvio condicional

Na Figura 163 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 microinstruo 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.

4 - Processadores

121

Registrador
Compare
Unidade
de
Controle

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

Na Figura 164 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 165: A unidade de controle da CPU-2, com destaque para a lgica de desvio

Quanto unidade de controle, as novidades so (veja a Figura 165):

temos uma entrada adicional que, como j dissemos, alimentada pelos trs bits do
registrador de comparao da calculadora

4 - Processadores

122

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 163, especificam a
condio de desvio . Essa confrontao dada pela expresso booleana
Desvio = (b21 AND D<ACC) OR (b20 AND D=ACC) OR (b19 AND 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 166, 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 166: 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.6 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:

programas, em sua forma de carga na memria do processador, so formados por


instrues;

4 - Processadores

123

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
avano com relao programao por sinais de controle.

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 167: Instrues Tpicas de uma CPU simples

A Figura 167 mostra alguns exemplos de instrues tpicas de CPUs simples. Como voc pode
reparar comparando com a Figura 166, 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.
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 168 voc pode ver um exemplo deste procedimento de
codificao em bits, que chamado de montagem da instruo.

4 - Processadores

124

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 168: Montagem de uma instruo

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. 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.

Sntese
Neste mdulo ns vimos processadores, que so circuitos lgicos que realizam
transformaes de informao de maneira flexvel, comandados por um programa
armazenado em sua memria. Este programa formado por bits que correspondem a
sinais de clock de flip-flops e registradores, de leitura e escrita de memrias, de posse e
liberao de barramentos, e fica armazenado em uma memria RAM.
Cada palavra da memria de programa abriga uma micro-instruo A execuo das
micro-instrues feita com o auxlio de um contador de programa, um registrador cuja
sada alimenta a entrada de endereo da memria de programa. Os bits da microinstruo corrente (aquela cujo endereo est no contador de programa) alimentam os
sinais de controle de um circuito igual a uma calculadora. Com a varredura sequencial
dos endereos da memria de programa, os bits de cada micro-instruo vo
comandando os sinais da calculadora, automatizando assim as aes de transferncias
de dados e de resultados de operaes aritmticas entre a memria e os registradores
da calculadora.
Algumas micro-instrues tambm podem codificar valores literais necessrios para o
programa. Outras, as chamadas micro-instrues de desvio, podem provocar alteraes
na ordem de execuo do programa.

Programas Scilab

126

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.Ziller42
Neste mdulo ns damos incio ao estudo de programao de computadores, agora utilizando
uma linguagem mais apropriada para humanos. Teremos o primeiro contato com o Scilab,
sistema e linguagem que utilizaremos neste curso.

42

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.

Programas Scilab

Tpicos
1.
2.
3.
4.
5.
6.
7.

Compiladores, interpretadores e sistemas operacionais


Scilab
Variveis e comandos de atribuio
Usando o Scilab como uma calculadora
Programas Scilab
Valores lgicos e strings
Os comandos if-then-else e printf

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
27. Descrever compiladores, interpretadores e sistemas operacionais
28. Construir expresses aritmticas Scilab que calculam frmulas matemticas
29. Descrever e construir comandos de atribuio
30. Utilizar a console do Scilab como uma calculadora
31. Criar, editar, salvar, recuperar e executar programas Scilab
32. Usar o comando input para obter valores do usurio em tempo de execuo
33. Descrever valores lgicos e cadeias de caracteres
34.
Interpretar e construir comandos de execuo condicional usando o
comando if-then-else
35. Usar o comando printf para exibir resultados na console

127

Programas Scilab

128

5.2 Compiladores, Interpretadores e Sistemas Operacionais

DR_Clk
Literal_Bus
In_Bus
In_Clk
MAR_Clk
RAM_Dbus
RAM_Clk
DR_Bus
Oper1
Oper0
Out_Clk
Compare_Clk
ACC_Bus
ACC_Clk
ACC_Clear

Literal?
Desvio?
Menor
Igual
Maior

Endereo

Ns vimos que processadores so circuitos de comportamento flexvel, ditado por programas


Micro-instruo
escritos por 23
humanos
para resolver problemas de transformao de informao. A facilidade
22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
de troca de comportamento, e a capacidade de prescrio
Sinais de atividades repetitivas como a
soma de 1 milho de nmeros faz do processador um instrumento muito poderoso.
Mas programar um processador, da forma como vimos, usando micro-instrues para indicar
bit a bit quais sinais devem ser ligados ou desligados, uma tarefa rdua mesmo para
transformaes de informao extremamente simples como somar dois nmeros.
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

1
0
0
1
0
0
1
0
0
0
1
0
0
0
0
0
0
0
0
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
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
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
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
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0

0
1
1
0
1
1
0
1
1
0
0
1
1
0
0
0
0
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
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
0
0
0
0
0
1
0
0
0
1
0
0
0
0
1
0
0

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

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

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
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
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
0
0
0
0
0
0
0
0
0
1
0
0
0
0
0
0
0
0
1
0
0
1
1

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

1
0
0
RAM(5) = 0
0
0
0
0
DR = 16
0
0
1
1
0
ACC = RAM(5)
0
0
0
0
0
ACC = ACC + RAM(DR)
0
0
1
0
RAM(5) = ACC
0
0
0

Figura 169: Parte de um programa que soma os valores entre as posies x10 e x50 da memria

Escrever ou compreender um programa como este mostrado na Figura 169 tarefa insana,
que pode ser aliviada com o uso de um formulrio e de instrues mais legveis para
humanos, como mostrado na Figura 170.

Programas Scilab

129

Figura 170: Mesmo programa da Figura 169 visto em formulrio com indicao dos campos e do efeito
acumulado de micro-instrues

Quando olhamos para a coluna Efeito Acumulado neste formulrio, ns vemos que (1) as
intenes do programador ali esto representadas de forma muito mais clara que os 1s e 0s do
programa propriamente dito, e (2) quanto ao significado, as instrues nessa coluna
especificam de forma inambgua o que deve ser feito. Isso leva naturalmente idia de se
construir um programa para automaticamente traduzir de uma notao efeito acumulado
para os bits que so carregados para execuo pelo processador.

Figura 171: Um programa montador auxilia a programar

O processo de montagem manual dos bits das instrues de um programa escrito com
mnemnicos pode ser feito com a ajuda de um montador (um assembler), um programa que l
outro programa escrito com mnemnicos e labels, e faz automaticamente a montagem das
instrues. A montagem manual de instrues foi feita somente 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

Programas Scilab

130

System, FORTRAN43, mostrado na Figura 172. Fortran sem qualquer dvida a me de todas
as linguagens. Tendo passado por diversas atualizaes, Fortran continua sendo 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
menor grau de sucesso muitas linguagens milhares delas, literalmente. Um mapa cronolgico
com as principais linguagens de programao pode ser encontrado na referncia44.

Figura 172: Fac-smile do relatrio de especificao da linguagem FORTRAN 45

Outras linguagens importantes que so sucessoras diretas de Fortran so:

43

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,

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

Programas Scilab

131

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).

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 173: 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 173 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

Programas Scilab

132

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
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.3 Scilab
Nos fins dos anos 70 Cleve Moler criou uma linguagem, Matlab46, 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.

46

Mathworks, MathWorks - MATLAB and Simulink for Technical Computing.

Programas Scilab

133

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.

Prompt de
Comandos

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

A Figura 174 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.4 Variveis e Comandos de Atribuio

a uma varivel
que passa a existir,
recebe e guarda um
valor

Variveis
criadas

O Scilab ecoa o
valor recebido pela
varivel

Figura 175: Um comando de atribuio

Histrico

Programas Scilab

134

O principal comando que transforma informao chamado comando de atribuio. Um


primeiro exemplo est na Figura 175, 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
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 176: Variveis e comandos de atribuio

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

Programas Scilab

135

Figura 177: Navegador de variveis aps a execuo dos comandos na Figura 176

Um comando de atribuio tem o formato


<varivel alvo> = <expresso>
onde:

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
A expresso pode conter b =
a varivel alvo, em uma
2048.

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

estrutura similar a um
registrador acumulador
Figura 178: Usos e erros em comandos de atribuio

Conforme ilustrado na Figura 178, 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 179: Exemplos de comandos de atribuio com variveis com valor pr-definido, supresso de eco e
funes elementares

Programas Scilab

136

O Scilab oferece tambm variveis com valores pr-definidos, como %pi ou %e, e uma
enorme variedade de funes pr-definidas (veja a Figura 180). 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.

Figura 180: 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
181 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

Operao

1a

Potenciao

2a

Multiplicao,
diviso

Programas Scilab

137

3a

Adio, subtrao

Figura 181: 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).

-->2^3*4
ans =
-->2^(3*4)
ans =
-->2^3^4
ans =
2.418D+24
-->2^(3^4)
ans =
2.418D+24
-->(2^3)^4
ans =
-->2*3+4
ans =
-->2*(3+4)
ans =

32.
4096.

4096.
10.
14.

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

Na Figura 182 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,
+ 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.5 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

Programas Scilab

138

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 183.
-->a = 534.2765
a =
534.2765
-->b = 9987.3431
b =
9987.3431
-->c = 225.7690
c =
225.769
Figura 183: Inicializao dos coeficientes de uma equao de 2o grau

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


-->delta = b^2 - 4*a*c
delta =
99264530.
-->r1 = (-b+sqrt(delta))/(2*a)
r1 =
- 0.0226329
-->r2 = (-b-sqrt(delta))/(2*a)
r2 =
- 18.670578
Figura 184: 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
+
) . ,
2

1 = (

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 185. Este
tipo de erro conhecido como erro de sintaxe.
-->delta = b^2 - 4ac
!--error 276
Operador, comma, ou semicolon faltante.
Figura 185: Mensagem de erro de sintaxe detetado pelo Scilab

Programas Scilab

139

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
aquele 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 186. 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.

-->a*r1^2 + b*r1 + c
ans =
3.865D-12
-->a*r2^2 + b*r2 + c
ans =
- 2.274D-13
Figura 186: Verificando os resultados

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 184 aumenta muito a confiana nos clculos.

5.6 Programas Scilab


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.
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 187 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.

Programas Scilab

140

Editor de
Programas

Figura 187: 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.


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.

Programas Scilab

141

Figura 188: O SciNotes editando o programa Eq2g1.sce

A Figura 188 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.

Figura 189: 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 189. 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.

Programas Scilab

142

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.

// Clculo das razes de uma


// de 2o grau
a = input("Digite o valor de
b = input("Digite o valor de
c = input("Digite o valor de
delta = b^2 - 4*a*c
r1 = (-b+sqrt(delta))/(2*a)
r2 = (-b-sqrt(delta))/(2*a)

equao
a:")
b:")
c:")

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

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

Digite
a =
1.
Digite
b =
2.
Digite
c =
3.
delta
- 8.
r1 =
- 1.
r2 =
- 1.

o valor de a:1
o valor de b:2
o valor de c:3
=
+ 1.4142136i
- 1.4142136i

Figura 191: Execuo do programa Eq2g2.sce

A Figura 191 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
negativo, e o exemplo serve tambm para ilustrar a naturalidade com que o Scilab trata
nmeros complexos.

5.7 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 192 mostra
um exemplo de atribuio de valores lgicos a variveis usando a console do Scilab.

Programas Scilab

143

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

%t

Literal True
Expresso
Relacional

5 > 2

p | q

OR
p & q

AND
~ s

NOT

Figura 192: 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 63 (pgina 54).

>
>=
<

maior que
maior ou igual a
menor que

<=

menor ou igual a

==

igual a

<> ou ~=

diferente de

Figura 193: Operadores relacionais

Expresses lgicas frequentemente fazem uso de comparaes entre valores de expresses


aritmticas para obter um valor lgico. A Figura 193 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.
-->a = 5 > 7
a =
F
-->b = (2+1) == 3
b =
T
-->c = (4-3) <= 0
c =
F
Figura 194: Exemplos de expresses lgicas utilizando operadores relacionais

Programas Scilab

144

Alm de valores lgicos, variveis Scilab podem armazenar outros dados no numricos. Na
Figura 195 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 195: 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 196: 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 197: Erro ao tentar representar um string contendo aspas

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 197.
Para conseguir isso, basta colocar duas aspas consecutivas na posio desejada, como na
Figura 198.
-->x = 'String ""com aspas duplas""'
x =
String "com aspas duplas"
-->x = 'String ''com aspas simples'''
x =
String 'com aspas simples'
Figura 198: Strings contendo aspas

Programas Scilab

145

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 61. Se tentarmos
realizar operaes aritmticas com strings de algarismos, o Scilab ir emitir uma mensagem de
erro apropriada:
-->2*'3.1415926'
!error 144
Undefined operation for the given operands
Figura 199: 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 200: Exemplos de uso do comando input na console do Scilab

5.8 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.

Programas Scilab

146

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 201: O programa Eq2g3.sce

A Figura 201 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 202: 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 202, 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.

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 203.
if <condio> then
<bloco ento>
else
// Nenhum comando aqui
end

if <condio> then
<bloco ento>
end

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

Programas Scilab

147

A Figura 204 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 204 :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 205 mostra uma sada do programa
Eq2g3.sce onde se pode ver o efeito da execuo deste comando.
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 205: Uma sada do programa Eq2g3.sce

Programas Scilab

148

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 206: O programa PassouNaoPassou.sce

A Figura 206 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 207: Duas execues do programa PassouNaoPassou.sce

Dois exemplos de execues deste programa esto na Figura 207. 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.

6 - Matrizes

149

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 - Matrizes

Tpicos
1.
2.
3.
4.
5.
6.

Matrizes
Construindo matrizes numricas
Matrizes e o comando de atribuio
Aritmtica matricial
Grficos
Funes teis

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
36.
37.
38.
39.
40.
41.
42.

Descrever matrizes com valores numricos, strings ou lgicos


Construir matrizes por comandos de atribuio
Utilizar o comando input para a leitura de matrizes
Construir vetores numricos regulares
Interpretar e construir expresses aritmticas com matrizes
Usar o Scilab para construir grficos
Atribuir e recuperar valores de um elemento ou de uma parte de uma matriz,
utilizando vetores de ndices ou vetores lgicos
43. Obter matrizes com valores lgicos por expresses relacionais
44. Utilizar funes para manipulao de matrizes de strings

150

6 - Matrizes

151

6.2 Matrizes e Comandos de Atribuio

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

2.
5.

3.
6.

Figura 208: Atribuindo valores literais a uma matriz

A Figura 208 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 209, e tambm podemos atribuir um valor a um
elemento especfico de uma matriz, como mostrado na Figura 210.

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

2.
5.

3.
6.

-->e = A(2,3)
e =
6.
Figura 209: 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 210: Atribuindo um valor a um elemento de uma matriz

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 211 mostra dois exemplos de uso da funo size.

6 - Matrizes

152
-->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 211: 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 212.

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

// matriz 1x1
= 13
0.
0.

0.
13.

Figura 212: Expanso de uma matriz

Vetores so matrizes de uma nica linha ou de uma nica coluna. A Figura 213 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 213: Um vetor linha e um vetor coluna

O Scilab permite que uma parte de uma matriz seja referenciada tanto para a atribuio de
valores como para a recuperao de valores armazenados.

6 - Matrizes

153
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.

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

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

28.
12.
77.
21.
11.

68.
15.
69.
84.
40.

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

23.
23.
21.
88.
65.

30.
93.
21.
31.
36.

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

Figura 214: 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 214.
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 215: Atribuindo os valores de uma matriz a uma parte de outra matriz

A Figura 215 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.

66.

23.

93.

56.

43.

-->a = x(2,:)
a =
75.

84.

Figura 216: 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 216 mostra um
exemplo de uso desta notao para obter todos os elementos em uma linha de uma matriz.

6 - Matrizes

154
x

=
91.
4.
48.
26.
41.

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 217: Obtendo os elementos de todas as linhas nas colunas de 3 a 5

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

6.3 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 218: Adio e subtrao de matrizes

A Figura 218 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

155
-->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 219: Exemplo de produto matricial

Na Figura 219 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 220: 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 220 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 221: 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 221.

6 - Matrizes

156
-->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 222: Exponenciao matricial (^) versus exponenciao elemento a elemento (.^)

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 222 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 223: Transpondo uma matriz

Se a uma matriz, adesigna a matriz transposta de a, como mostrado na Figura 223.


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 224: A funo inv, que produz a matriz inversa

A funo inv produz a matriz inversa da matriz dada como argumento. A Figura 224 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 225.

6 - Matrizes

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

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

Figura 225: 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 226.

6 - Matrizes

158
-->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 226: Resolvendo um sistema de equaes lineares

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

6.4 Construindo matrizes


Vetores com valores regularmente espaados podem ser construdos como mostrado na
Figura 228.
-->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

10.

13.

Figura 228: 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 228.
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 229 mostra dois
exemplos de uso da funo linspace.

6 - Matrizes

159

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 229: 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 230.
-->x = zeros(2,3)
x =
0.
0.
0.
0.
0.
0.
-->y = ones(2,3)
y =
1.
1.
1.
1.
1.
1.
Figura 230: 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 231.
-->I = eye(4,4)
I =
1.
0.
0.
0.
1.
0.
0.
0.
1.
0.
0.
0.

0.
0.
0.
1.

Figura 231: 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
232 mostra dois exemplos de uso desta funo.

6 - Matrizes

160

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 232: 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 233: 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 233.
-->sqrt([4 9 16 25])
ans =
2.

3.

4.

5.

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

A Figura 234 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.5 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

161

-->x = [1 4 7 11]; y = [12 6 15 7];


-->plot2d(x,y)

7,15

15

14

13

1,12

12

11

10

11,7

6
1

10

11

Figura 235: Exemplo de grfico obtido com plot2d

A Figura 235 mostra um exemplo de grfico obtido com o comando plot2d; outro exemplo
est na Figura 236, 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 236: Outro exemplo de grfico obtido com plot2d

Para se obter um grfico da funo seno, podemos fazer como mostrado na Figura 237.
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

162
-->x = 0:0.8:3*%pi;
-->y = sin(x);
-->plot2d(x,y)
1.0
0.8

0.6
0.4

0.2

O espaamento
de 0.8 est
grande!

0.0
-0.2

-0.4
-0.6

-0.8
-1.0
0

Figura 237: 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
238.

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

Com 101 pontos


temos uma curva
mais suave

32

Figura 238: 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

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

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

0.6
0.4

0.2

0.0
-0.2

-0.4
-0.6

-0.8
-1.0
0

10

Figura 239: Grfico com vrias curvas obtido com plot2d

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

6.6 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 240 gera o grfico da Figura 241.
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 240: Exemplo de uso de plot3d

Figura 241: (, ) = ()()

Se substituirmos a funo por z(i,j) = 10 -(x(i)^2 + y(j)^2), por exemplo,


vamos obter o grfico da Figura 242.

6 - Matrizes

164

Figura 242: (, ) = ( + )

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 243, 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 243: Exemplo de uso de plot3d1 com mapa de cores

6 - Matrizes

165

Figura 244: (, ) = ()() 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 245: Rotao do grfico da Figura 244

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.7 Matrizes de Strings


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

6 - Matrizes

166
-->a = ["s1" "s2"]
a =
!s1 s2 !
-->b = ["s1" ; "s2"]
b =
!s1 !
!
!
!s2 !
Figura 246: Exemplos de matrizes de strings

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 247.
-->tokens("C:\Users\Osvaldo\Dropbox\Ensino\dcc001\2012-2\Mdulo 06","\")
ans =
!C:
!
!Users
!
!Osvaldo
!
!Dropbox
!
!Ensino
!
!dcc001
!
!2012-2
!
!Mdulo 06

!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
Figura 247: 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 248.
-->t = tokens('Ouviram do Ipiranga as margens plcidas")
t =
!Ouviram
!
!do
!
!Ipiranga
!
!as
!
!margens
!
!plcidas

!
!
!
!
!
!
!
!
!
!
!

Figura 248: 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

167

6.8 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 249.
-->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 249: 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 250 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 250: 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 251: Uso de matriz booleana para seleo de elementos de uma matriz

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

6 - Matrizes

168
-->a = [3
-->a(a>5)
a =
3. - 1.

9; 12 1];
= -1
1.
1.

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

7 - Loops

169

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 - Loops

170

Tpicos
1.
2.
3.
4.
5.
6.
7.
8.
9.

O comando while
Soma dos elementos de um vetor
Menor valor presente em um vetor
Loop para o clculo de fatorial
O algoritmo de Euclides para o mximo divisor comum
O comando for
Gerao e impresso de tabelas
Gerao e impresso de uma tabuada de multiplicao
Arquivos

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
45.
46.
47.
48.
49.

Descrever a sintaxe e a semntica do comando while


Construir loops usando o comando while
Explicar loops clssicos: soma, mnimo, fatorial, ...
Descrever a sintaxe e a semntica do comando for
Utilizar comandos bsicos para leitura e escrita de arquivos com mgetl, fscanfMat e
fprintfMat

7 - Loops

171

7.2 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 201.
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 253.
continua = %T;
while continua
// Processamento de um item
...
// Deciso
decisao = ...
input('Continua? (s/n)','string');
continua = decisao == 's';
end
printf('\nObrigado!');
Figura 253: 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

172
// 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

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 254: 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 255. 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 255: Um loop infinito

7.3 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

173
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 256: Clculo de fatorial utilizando o comando while

J temos condies de compreender o cdigo mostrado na Figura 256, 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 256 a propriedade fat == (k-1)! um
invariante do loop. Um exemplo de execuo deste loop est na Figura 257.
Invariante:
fat sempre contm o fatorial de k-1

fat 1

A cada passo,
fat
multiplicado por k

k incrementado
a cada passo

Valores iniciais colocados


na preparao do loop

24 120

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

Figura 257: Exemplo de clculo do fatorial usando o loop da Figura 256

7.4 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 258 mostra como faz-lo utilizando um
loop, fazendo uma soma de cada vez, como provavelmente implementada a funo sum.

7 - Loops

174
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 258: Loop para soma dos elementos de um vetor

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

Em cada
passo,
A(i)
somado a s

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

Valores iniciais colocados


na preparao do loop

16 19 24

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

Figura 259: Exemplo de clculo da soma dos elementos de um vetor pelo loop da Figura 258

7.5 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

175
end
// m == min(A(1:k-1)) e k == n + 1;
// portanto, m = min(A(1:n))
Figura 260: Loop para encontrar o menor valor presente em um vetor

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 261.

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))

<

<

<

<

10

3
Invariante:

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

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

7.6 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 hoje47! 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
= .
47

Euclidean algorithm - Wikipedia, the free encyclopedia, acessado 8 de maro de 2011,


http://en.wikipedia.org/wiki/Euclidean_algorithm#cite_note-2.

7 - Loops

176

onde 1 um inteiro. Temos ento


= ( )
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 262.
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 262: 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 263 mostra um exemplo de execuo deste loop.

7 - Loops

177

m
n

56
12

56

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

44

12

Valores iniciais colocados


na preparao do loop

32

12

20

12

12

12

Em cada passo, o maior


entre a e b substitudo
pela diferena

O loop termina
quando a = b

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

7.7 O comando for


Loops como o da Figura 256 so to freqentes em programao que existe um outro
comando, o for, que substitui o comando while com vantagens em alguns casos. Na Figura
264 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 264: 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 265.
for <varivel> = <vetor>
<bloco for>;
End
Figura 265: Forma geral de um comando for

Aqui <vetor> contm os valores atribudos varivel indexadora <varivel> a cada


iterao do loop.

7 - Loops

178

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

=
=
=
=
=

1
3
5
7
9

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

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

No exemplo da Figura 266,

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.

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

Sada

Figura 267: Exemplo de for com passo negativo

O passo de um for pode ser negativo, como mostrado na Figura 267, e a varivel de controle
pode assumir valores no inteiros, como na Figura 268.
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 268: Exemplo de for com a varivel de controle assumindo valores no inteiros

7.8 Gerao e Impresso de Tabelas

7 - Loops

179
x
0.0
0.2
0.4
0.6
0.8

seno(x)
0.0000
0.1987
0.3894
0.5646
0.8415

Figura 269: Tabela de Senos

Vamos agora usar o comando for para a construo de uma tabela como a da Figura 269 ,
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 270: O programa Tabela_de_Senos_1.sce

O programa da Figura 270 parece atender especificao, mas quando executado pelo Scilab
produz uma sada de difcil compreenso, como mostrado na Figura 271.
-->
0 00.2 0.1986690.4 0.3894180.6 0.5646420.8 0.7173561 0.841471
Figura 271: 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 272.
// Tabela da funo Seno
for x = 0:0.2:2*%pi
printf("\n%g %g",x, sin(x))
end
Figura 272: O programa Tabela_de_Senos_2.sceFigura 269

A sada do Tabela_de_Senos_2.sce, cujas primeiras linhas esto mostradas na Figura 273,


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 273: 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

180

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 274: O programa Tabela_de_Senos_3.sce

A Figura 274 mostra o programa Tabela_de_Senos_3.sce que produz a sada mostrada


parcialmente na Figura 275.
x
0.0
0.2
0.4
0.6
0.8
1.0
1.2

seno(x)
0.0000
0.1987
0.3894
0.5646
0.7174
0.8415
0.9320

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

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.

Todo comando for pode ser substitudo por um comando while; a Figura 276 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.

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

x = 0;
while x <= 2*%pi
printf("\n%3.1f %7.4f",...
x, sin(x))
x = x+0.2;
end

Figura 276: Mesmo loop obtido com comandos for e while

7 - Loops

181

7.9 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 1. Exemplos seriam Paulo, com 81 pontos voc
obteve o conceitoB!, ou Paulo, com 90 pontos voc obteve o conceito A!
Tabela 1: 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 277, 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

182

// 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 277: O programa PontosConceito.sce

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

183
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

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

Mais legvel

Menos legvel

Figura 278: 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 278 e a Figura 279 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 279: Outro exemplo da influncia da indentao na legibilidade de um comando

7.10 Gerao e Impresso de uma Tabuada de Multiplicao


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

7 - Loops

184
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

Figura 280: 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 281.
// Tabuada de multiplicao
for linha = 1:9
for coluna = 1:9
printf("%g",linha*coluna);
end
end
Figura 281: 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 282: 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.11 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

185

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.

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
283 mostra a janela de navegao para escolha de um arquivo aberta no Windows Vista aps a
execuo de um comando uigetfile.

Figura 283: 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 284.
-->f = uigetfile(title="Escolha um arquivo:")
f =
C:\Users\Osvaldo\Documents\dcc\Ensino\dcc001\Scilab\Dados\ConstrCivil.txt
Figura 284: 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

186
o
o

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 285 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 285: Exemplo de uso dos comandos uigetdir e listfiles

7.12 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 286: Leitura de um arquivo como um vetor coluna de strings usando o comando mgetl

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

7 - Loops

187
-->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?

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

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

Na Figura 287 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.13 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 288: Gravao de uma matriz em um arquivo com fprintfMat

Na Figura 288 ns vemos um exemplo de uso do comando fprintfMat. O resultado deste


programa um arquivo como o mostrado na Figura 289.

Figura 289: Arquivo gerado pelo programa da Figura 288

Se agora executarmos o programa da Figura 290, escolhendo como entrada o arquivo da


Figura 289, iremos obter uma matriz m idntica matriz a gravada anteriormente.

7 - Loops

188

arquivo = uigetfile();
m = fscanfMat(arquivo)
Figura 290: Leitura de uma matriz com o comand fscanfMat

Vamos agora ver um exemplo de aplicao de matrizes e arquivos. A Figura 291 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 291: 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 291;
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 292: O programa ClimaBHZ.sce

A Figura 292 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

189

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

Graus C

25

20

15

10

0
0

2
MaxMed
MinMed
MaxRec

6
Ms

8
MinRec

10

12

Figura 293: Grfico gerado pelo programa da Figura 292


Na

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

7.14 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 294.

7 - Loops

190
6

0
0

Figura 294: 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 295.
6

0
0

Figura 295: 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 296, onde o ponto final do primeiro polgono e o ponto
inicial do segundo polgono foram (naturalmente) emendados pelo Scilab.

7 - Loops

191

0
0

Figura 296: 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 48, e
de onde retiramos grande parte desta seo). Se voc abrir este arquivo com um editor de
arquivos texto como o PSPad49 (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.

48

Applications with Scilab, Maxima, Geogebra, acessado 28 de setembro de 2011,


http://www.wolffdata.se/.
49
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

192

Figura 297: 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

193

8 Funes
Em linguagens de programao funes so uma ferramenta de modularizao da mais alta
importncia para o desenvolvimento de programas, e tambm um mecanismo lingustico para
a prescrio de comportamentos repetitivos.
Neste mdulo ns apresentaremos a sintaxe e a semntica de funes, formas de
programao de funes no Scilab, sua utilizao no desenvolvimento de programas e no
encapsulamento de detalhes. Veremos tambm como funes implementam o conceito de
recurso, central na Cincia da Computao.

8 - Funes

194

Tpicos
1.
2.
3.
4.
5.
6.

Funes e reaproveitamento de cdigo


Forma e funcionamento
Funes, arquivos-fonte e o Scilab
Funes e desenvolvimento top-down
Funes e encapsulamento de detalhes (e mais sobre arquivos)
Funes recursivas

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
1. Explicar a sintaxe e a semntica de funes Scilab
2. Construir funes no ambiente Scilab, com a utilizao de um nico arquivo ou de
arquivos distintos
3. Explicar a utilidade de funes como ferramenta de modularizao de software
4. Utilizar funes no desenvolvimento top-down de programas
5. Codificar comandos para leitura e gravao de arquivos em formatos CSV e colunas
pr-fixadas
6. Explicar o funcionamento de funes recursivas
7. Utilizar funes recursivas para a prescrio de loops

8 - Funes

195

8.2 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 298.
fat = 1;
for i = 1:n
fat = fat*i;
end
Figura 298: 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 299, onde cada clculo de fatorial est
destacado, e onde o comando de sada foi omitido.

Figura 299: Programa para clculo do nmero de combinaes de n k a k

Voc deve reparar que foram feitas trs adaptaes do cdigo, uma para cada fatorial a ser
calculado. Repare que em cada adaptao:

A varivel v recebe um valor inicial que depende do fatorial que se quer calcular;
Ao trmino do clculo do fatorial, o valor da varivel fat atribudo uma varivel
que armazena o fatorial calculado, e
Os comandos que efetivamente calculam o fatorial so os mesmos, replicados para
cada fatorial a ser calculado.

8 - Funes

196

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.

Figura 300: Clculo de combinaes: cdigo com o uso de funo

O programa da Figura 300 equivalente ao da Figura 299, 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.
O cdigo na parte superior da Figura 300 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. No exemplo, os valores a serem atribudos varivel v e as variveis que
recebem o valor da varivel fat so o que chamamos, respectivamente, de parmetros de
entrada e parmetros de sada das chamadas da funo. 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 299, 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 299
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 309 em uma funo, o
que resulta no cdigo mostrado na Figura 301.
function nComb = Combinacoes(n,k)
nComb = fatorial(n) / (fatorial(n-k) * fatorial(k))
endfunction
Figura 301: Uma funo para o clculo do nmero de combinaes de n k a k

Um programa equivalente ao da Figura 309 est mostrado na Figura 302. 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.

8 - Funes

197
exec("Combinacoes.sci")
exec("fatorial.sci")
n=input("n="); k=input("k=");
printf("nComb(%d,%d) = %d",n,k,Combinacoes(n,k))
Figura 302: Um programa principal que usa a funo Combinacoes

A Figura 303 ilustra o encadeamento das chamadas neste programa.


Programa
Principal

Funo
nComb
Funo
Fatorial
Figura 303: Encadeamento de chamadas

8.3 Forma e Funcionamento


function fat = fatorial(n)
fat = 1;
for i = 1:n
fat = fat*i;
end
endfunction
Figura 304: 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 305: 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
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 denominados
parmetros reais; so expresses que produzem ou recebem valores. No incio da execuo da

8 - Funes

198

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 306 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 306: 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 305 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 307 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

199
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 307: Uma funo que faz o grfico de outra funo recebida como parmetro

8.4 Funes, arquivos fonte e o Scilab


No Scilab voc pode colocar em um mesmo arquivo o programa principal e todas as funes
que so utilizadas, mas pode tambm utilizar arquivos separados para armazenar o cdigo de
funes. O primeiro mtodo o mais simples, mas existem vantagens na utilizao do segundo
mtodo. Se o cdigo de uma funo se encontra repetido em diversos arquivos, junto com os
programas que a utilizam, uma melhoria nesse cdigo, ou a correo de um erro, envolve a
atualizao de todos os arquivos. Caso a funo esteja armazenada em um arquivo separado,
qualquer atualizao desta funo se reflete em todos os programas que a utilizam.
Usando o segundo mtodo, a 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 308: Um arquivo com uma funo aberto no SciNotes

A Figura 308 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.

8 - Funes

200

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 309.
exec("fatorial.sci")
n=input("n="); k=input("k=");
nComb = fatorial(n) / (fatorial(n-k) * fatorial(k))
Figura 309: Programa principal para o clculo de combinaes com o comando exec

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.

8.5 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.12 como ler e escrever todas as linhas de um arquivo com os
comandos mgetl e mputl, e na Seo 7.13 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 310.
d = mopen(arquivo);
// operaes de leitura ou de escrita
mclose(d);
Figura 310: 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.

8 - Funes

201

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

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

Colunas
Inicial
Final
1
4
5
12
13
13
14
50

Contedo
Ano de registro
Nmero de cadastro
em branco
Nome

Figura 312: Descrio do arquivo da Figura 311

A Figura 313 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 313: Funo para leitura do arquivo da Figura 311

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:

8 - Funes

202
-->length("
ans =
11.

abc

")

-->length(stripblanks("
ans =
3.

abc

"))

A Figura 314 mostra uma funo que faz a operao inversa, isto , grava um arquivo com o
formato da Figura 311 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 314: 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 315: Primeiras linhas de um arquivo em formato CSV

Na Figura 315 ns vemos as mesmas informaes do arquivo da Figura 315 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 316: Funo para leitura de um arquivo com o formato CSV da Figura 315

8 - Funes

203

A Figura 316 mostra uma funo que l um arquivo com o formato da Figura 316. 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.
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 317: Funo para gravao de um arquivo em formato CSV

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

8.6 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 318.
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 318: 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,

8 - Funes

204

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.

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 319.
function p = MenorPrimoMaiorOuIgualA(n)
p = n;
while ~Primo(p)
p = p+1
end
endfunction
Figura 319: 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 320,
function ehPrimo = Primo(n)
ehPrimo = (n == MenorFator(n));
endfunction
Figura 320: 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 321: A funo MenorFator

Com isso ns terminamos o desenvolvimento do nosso programa. importante que voc


observe os ganhos obtidos com esse enfoque:

8 - Funes

205

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;
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.7 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 322 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 322: 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 323.

8 - Funes

206
// 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 323: Programa TestaFatorialR.sce

Considere tambm a verso de fatorialR da Figura 324, 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 324: A funo fatorialR, instrumentada para acompanhamento de sua execuo

A execuo deste programa pode gerar a sada mostrada na Figura 325, 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 325: 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)

Prog

Fat(2)

Fat(2)

Fat(2)

Fat(3)

Fat(3)

Fat(3)

Fat(3)

Fat(3)

Fat(4)

Fat(4)

Fat(4)

Fat(4)

Fat(4)

Fat(4)

Fat(4)

Fat(5)

Fat(5)

Fat(5)

Fat(5)

Fat(5)

Fat(5)

Fat(5)

Fat(5)

Fat(5)

Prog

Prog

Prog

Prog

Prog

Prog

Prog

Prog

Prog

Figura 326: Pilha de execuo de FatorialR

Prog

8 - Funes

207

A Figura 326 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 327.
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 327: Funo MinimoR, recursiva

9 Algoritmos, Pesquisa

208

9 Algoritmos
Com este mdulo ns damos incio terceira e ltima unidade deste curso, intitulada
Algoritmos. Ns continuaremos a utilizar Scilab como linguagem de programao, mas esta
unidade teria em essncia o mesmo contedo, caso tivssemos adotado neste curso Java,
Python, C ou qualquer outra linguagem. Veremos algoritmos para a fatorao de nmeros
inteiros, e tambm algoritmos para pesquisa em tabelas.

9 Algoritmos, Pesquisa

Tpicos
1.
2.
3.
4.
5.

Definio e caractersticas
Fatorao
Melhorando a fatorao
Pesquisa Sequencial
Pesquisa Binria

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
1.
2.
3.
4.
5.
6.
7.

Explicar os conceitos de algoritmo, especificao, correo e eficincia


Explicar o conceito de complexidade de algoritmos
Explicar a notao big O para funes de complexidade
Determinar funes de complexidade de algoritmos simples
Explicar os algoritmos de pesquisa sequencial e de pesquisa binria
Construir programas com aplicaes de algoritmos de pesquisa
Avaliar algoritmos de pesquisa em funo de sua complexidade

209

9 Algoritmos, Pesquisa

210

9.2 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, 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.
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

9 Algoritmos, Pesquisa

211

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 328: 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 328, 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 98 (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.3 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

9 Algoritmos, Pesquisa

212

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 329: O programa Fatora.sce

Na Figura 329 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 321. 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

Figura 330: Tempos para fatorar nmeros primos e no primos

Na Figura 330 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
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

9 Algoritmos, Pesquisa

213

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 50, contm arquivos com nmeros primos ou programas que geram nmeros
primos. A Figura 331 mostra as primeiras e ltimas linhas deste arquivo.

Figura 331: 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 332.
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 332: 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.

50

The Prime Pages (prime number research, records and resources), acessado 7 de maro de 2011,
http://primes.utm.edu/index.html.

9 Algoritmos, Pesquisa

214

Tabela 2: Tempos (segundos) gastos com a funo MenorFator em um notebook e em um desktop

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 2 mostra os
resultados obtidos com diversos nmeros primos, em experimentos realizados com dois
computadores com velocidades distintas. O grfico da Figura 333 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 333: Tempo para fatorao em funo do valor de nmeros primos em dois computadores

9 Algoritmos, Pesquisa

215

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 321) 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 334: 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

216

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.

9.4 Melhorando a Fatorao


Vamos agora considerar a funo MenorFator2, mostrada na Figura 335, 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 335: 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

Funo de
complexidade

217
Tamanho da Instncia do Problema
10

20

30

40

50

60

0,00001 0,00002 0,00003 0,00004 0,00005 0,00006


segundos segundos segundos segundos segundos segundos

n2

0,0001
0,0004
0,0009
0,0016
0,0025
0,0036
segundos segundos segundos segundos segundos segundos

n3

0,001
0,008
0,027
0,064
0,125
0,216
segundos segundos segundos segundos segundos segundos

n5

0,1
3,2
24,3
1,7
5,2
13,0
segundos segundos segundos minutos minutos minutos

2n

0,001
1,0
17,9
segundos segundos segundos

3n

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 336: Quadro comparativo de funes de complexidade

A Figura 336, extrada do livro de Garey e Johnson51, 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

10 M

31,6 M

n3

4,64 Z

10 Z

n5

2,5 W

3,98 W

2n

X + 6,64

X + 9,97

3n

Y + 4,19

Y + 6,29

Figura 337: 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 337, que
tambm foi retirada da referncia52. 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.

51

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.]).
52
Ibidem.

9 Algoritmos, Pesquisa

218

9.5 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.6 Pesquisa Seqencial


A Figura 338 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 338:O programa VerificaPrimos3.sci, que utiliza pesquisa seqencial

A funo Primo3 apenas um envelope sobre uma funo de pesquisa seqencial, como
mostra a Figura 339.

9 Algoritmos, Pesquisa

219

function ePrimo = Primo3(n,tabela)


ePrimo = seqSearch(n,tabela) ~= -1;
endfunction
Figura 339: A funo Primo3

A funo seqSearch mostrada na Figura 340 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 340: 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.7 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

220

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 341: A funo recursiva BinarySearch

A Figura 341 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 342: A funo binSearch

A funo binSearch (Figura 342) 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

221

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

222

10 Ordenao
Continuando nosso tour por algoritmos famosos da Cincia da Computao, este mdulo ns
vamos visitar o problema da ordenao dos elementos de um vetor. Veremos mtodos simples
e sofisticados de ordenao por comparaes, e tambm um mtodo de ordenao por
radical. O problema da ordenao 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 343.
1

34 56 27 45 12 44 34
1

12 27 34 34 44 45 56

Vetor no
ordenado
Vetor
ordenado

Figura 343: Ordenao de um vetor

Uma outra forma de se ver o efeito de uma operao de ordenao est ilustrada na Figura
344.

Figura 344: 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 - Ordenao

Tpicos
1.
2.
3.
4.
5.

Ordenao por Seleo


Ordenao por Intercalao
Ordenao por Partio
Dividir para Conquistar
Ordenao por Radical

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
1.
2.
3.
4.
5.
6.
7.
8.

Explicar o conceito de ordenao de vetores


Explicar o algoritmo de ordenao por seleo e sua complexidade
Programar algoritmos simples para ordenao
Explicar o algoritmo de ordenao por intercalao (merge sort) e sua
complexidade
Explicar o algoritmo de ordenao por partio (quicksort) e sua complexidade
Utilizar recursividade para a soluo de problemas de programao
Explicar o algoritmo de ordenao por radical (radix sort) e sua complexidade
Avaliar algoritmos de ordenao por sua complexidade

223

10 - Ordenao

224

10.2 Ordenao por Seleo


O primeiro algoritmo que iremos estudar conhecido como o mtodo de Seleo (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
345.
function sA = SelectSort(A)
// Constri o vetor sA com os
// mesmos elementos do vetor A
// dispostos em ordem crescente.
endfunction
Figura 345: Cabealho de uma funo de ordenao

Isso j nos permite desenvolver um programa para testar a funo, mostrado na Figura 346.
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 346: O programa SelectSort_teste.sce

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 347 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.

10 - Ordenao

225
1

34 56 27 45 12 44 34
1

12 56 27 45 34 44 34
1

12 27 56 45 34 44 34
1

12 27 34 45 56 44 34
1

12 27 34 34 56 44 45
1

12 27 34 34 44 56 45
1

12 27 34 34 44 45 56
Figura 347: Ordenao por Seleo e Troca

Figura 348: 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 349.

10 - Ordenao

226

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 349: 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 260), 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.
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 350: A funo SelecionaMenor

Como voc pode reparar na Figura 350, 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.

10 - Ordenao

227

// 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 351: O programa MinimoPos_teste e a funo PrintMatrix

A Figura 351 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
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 352 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 352: 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 353.

10 - Ordenao

228
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 353: 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) =

( 1) 2
=
2
2
1

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 354 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.

10 - Ordenao

229

Figura 354: Tempos medidos para ordenao por seleo e troca de vetores aleatrios em um notebook (*) e em
um desktop (+)

10.3 Intercalao (MergeSort)


a
1

b
3

15 15 19 22
1

10 16 19 20 23 27

Intercalao de a e b
3 4 5 6 7 8

10

10 15 15 16 19 19 20 22 23 27
Figura 355: 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 355. 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 356 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

230

12 72 26 54 98 73 0 59 30 25 62 11 61 67 33 2

16

12 72 26 54 98 73 0 59

12 72 26 54

12 72

12

98 73 0 59

26 54

72

26

12 72

54

98 73
98

26 54

73
73 98

12 26 54 72

0 59
0

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

61 67 33 2
62 11

25

25 30

62

61 67
11

11 62

61

33 2
67

33

61 67

11 25 30 62

2 33

2 33 61 67

2 11 25 30 33 61 62 67

0 2 11 12 25 26 30 33 54 59 61 62 67 72 73 98

16

Figura 356: 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 357
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.
60 85 6 82 92 56 57 81 5 55

10

60 85 6 82 92

60 85 6

56 57 81

60 85

60

85

82 92
6

56 57 81 5 55

82

60 85

92
82 92

6 60 85

56 57
56

5 55
57

81

56 57

55

5 55

56 57 81

6 60 82 85 92

10

5 55 56 57 81

6 55 56 57 60 81 82 85 92

Figura 357: Exemplo de ordenao por intercalao com n = 10

O cdigo da funo MergeSort est mostrado na Figura 358. 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

231
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 358: A funo MergeSort

A codificao da funo Merge (Figura 359) 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 359: A funo Merge

12 72 26 54 98 73 0 59 30 25 62 11 61 67 33 2

16

10 - Ordenao

232
12 72 26 54 98 73 0 59

30 25 62 11 61 67 33 2

12

72
12 72

26

54
26 54

12 26 54 72

98

73
73 98

59
0 59

0 59 73 98

30

25

25 30

62

11

11 62

11 25 30 62

61

67

33

61 67

2 33

16 passos
16 passos

2 33 61 67

16 passos
8

0 12 26 54 59 72 73 98

2 11 25 30 33 61 62 67

4 = log2(16)

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 e302562 da
11 ordem61 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 360.
33 2
ordenao

16 passos
16

0 2 11 12 25 26 30 33 54 59 61 62 67 72 73 98
Figura 360: 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.

10 - Ordenao

233

Figura 361: Comparao de desempenho SelectSort vs MergeSort

A Figura 361 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 362: Grfico de desempenho para a funo MergeSort

Na Figura 362 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.4 Partio (QuickSort)


Considere um vetor como o da Figura 363. 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

234

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 364 mostra uma ilustrao grfica de um vetor particionado.

93

100 56

12

123 100 231 212 112

Figura 363: Um vetor particionado

Figura 364: 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.

52
1

piv
6

10

inf

sup

17 78 81 27 52 86 65 24 97 54

i < inf

A(i)

piv

i > sup

A(i)

piv

Figura 365: Incio de uma operao de partio

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.

10 - Ordenao

235

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.
14 0

11 6

11 12 14 12 13 6

11 12 6

12 13 14

11 12 6

12 13 14

12 11 12 13 14

11 12 12 13 14

11 12 12 13 14

12 2

12 13 6

Esquerda
Meio
Direita
x Piv

Figura 366: Exemplo de ordenao por partio (quicksort)

A Figura 366 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 367: 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 367.

10 - Ordenao

236

Figura 368: 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 369.


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 369: 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;

10 - Ordenao

237

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.

Figura 370: Comparao entre SelectSort, MergeSort e QuickSort

10 - Ordenao

238

Figura 371: Comparao entre MergeSort e QuickSort

Figura 372: Teste de desempenho do quicksort

Na Figura 372 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 373.

10 - Ordenao

239

Figura 373: Elementos ordenados por unidade de tempo, em funo do tamanho do vetor

10.5 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 ;
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.6 Ordenao por Radical

10 - Ordenao

240

Figura 374: Um carto perfurado53

Figura 375: A classificadora de cartes IBM Type 82, de 194954

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 375) 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
53

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.
54
IBM Card Sorters, acessado 22 de fevereiro de 2012,
http://www.columbia.edu/cu/computinghistory/sorter.html#references.

10 - Ordenao

241

eram ativados para distribuir os cartes nos escaninhos segundo o valor perfurado na coluna
menos significativa.
506
021
688
115
489
529
541
658
012
719
508
784
792

0 21
5 41
0 12
7 92
7 84
115
5 06
688
6 58
508
4 89
529
7 19

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

1
2
021 012
541 792

0
1
2
506 012 021
508 115 529
719

0
1
012 115
021

4
5
6
784 115 506

4
5
541 658

8
9
688 489
658 529
508 719

8
9
784 792
688
489

4
5
6
7
489 506 658 719
508 688 784
529
792
541

021
541
012
792
784
115
506
688
658
508
489
529
719

506
508
012
115
719
021
529
541
658
784
688
489
792

012
021
115
489
506
508
529
541
658
688
719
784
792

Figura 376: 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 376
mostra as trs distribuies necessrias para a ordenao completa de um conjunto de
cartes.

11 - Algoritmos Numricos

242

11 Algoritmos Numricos
Algoritmos numricos lidam com representaes de nmeros reais com um nmero finito de
bits, e por isso tm caractersticas que os distinguem dos algoritmos que vimos at agora. Ns
veremos algoritmos para integrao numrica, para a determinao de razes de funes e
para o clculo de funes por sries de Taylor. Teremos tambm ocasio de apontar
problemas que podem ocorrer com implantaes desavisadas desses algoritmos.
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, nossa motivao pedaggica, pois estaremos desenvolvendo funes que j existem no
Scilab: integrate e intg calculam integrais definidas, fsolve resolve sistemas de
equaes no lineares, e exp calcula .

11 - Algoritmos Numricos

Tpicos
1. Integrao por Trapzios
2. Bisseo
3. Srie de Taylor para exp(x) e cancelamento catastrfico

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:
1. Explicar o algoritmo de integrao por trapzios
2. Explicar o algoritmo de determinao de razes de uma funo pelo mtodo da
bisseo
3. Explicar o mtodo de integrao por Monte Carlo
4. Explicar problemas de truncamento e arredondamento inerentes utilizao de
ponto flutuante
5. Construir programas numricos simples
6. Avaliar algoritmos numricos por sua velocidade de convergncia

243

11 - Algoritmos Numricos

244

11.2 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 direito de
cada retngulo
coincide com a
curva

O lado esquerdo
de cada retngulo
coincide com a
curva

rea =
f(xi+1).x

rea =
f(xi).x
xi

xi+1

xi

xi+1

Figura 377: reas cobertas pelas somas de Riemann pela esquerda e pela direita para () = no intervalo
[0,1]

A Figura 377 e a Figura 378mostram 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.

O lado esquerdo de
cada retngulo
coincide com a curva

O lado direito de
cada retngulo
coincide com a curva

Figura 378: 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 379.

11 - Algoritmos Numricos

245

Figura 379: Somas de Riemann com 16 intervalos

As frmulas das somas de Riemann levam diretamente s implementaes em Scilab,


mostradas na Figura 380 e na Figura 381.
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 380: Funo para o clculo da soma de Riemann esquerda

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 381: 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;

11 - Algoritmos Numricos

246

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 382.

rea do sub-intervalo =
x.(f(xi) + f(xi+1))/2

xi

xi+1

Figura 382: 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 383.
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 383: Funo para aproximao de integrais por trapzios

Para testar esta funo, vamos calcular 0 sin() , cujo valor exato ns sabemos:

11 - Algoritmos Numricos

247

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.3 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 384.

Figura 384: 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 385.

Figura 385: 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 386.

11 - Algoritmos Numricos

248

Figura 386: 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 387: 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

249

Figura 388: Caso em que a raiz est " esquerda" do ponto mdio do intervalo

Temos trs casos possveis. No primeiro (Figura 388) verificamos que (). () < 0, e
portanto que o intervalo [, ] contm pelo menos uma raiz, onde o algoritmo pode ser
reaplicado.

Figura 389: Caso em que a raiz est " direita" do ponto mdio do intervalo

No segundo caso (Figura 389) 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

250

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 390: Cabealho da funo bissecao

A Figura 390 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 391: Grfico de () =

A funo () = sin , cujo grfico est mostrado na Figura 391, 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 392 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 392: A funo exp_sin

11 - Algoritmos Numricos

251

O grfico da Figura 391 pode ser obtido na console do Scilab com os comandos mostrados na
Figura 393. 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 393: Comandos para obter o grfico da Figura 391 na console do Scilab

Com isso ns j podemos construir um programa testador para a funo bissecao,


conforme mostra a Figura 394. 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 394: 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 395 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 395: Primeiro refinamento da funo bissecao

O refinamento da reduo do intervalo simplesmente a codificao do mtodo da bisseo,


como mostra a Figura 396. 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

252

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 396: A funo bissecao

A Figura 397 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 397: Teste da funo bissecao

11.4 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 +

2 3
+ + +
1! 2! 3!

ou, lembrando que 0! = 1,

=
=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
398.

11 - Algoritmos Numricos

253

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 398: Cabealho da funo expTaylor

Para testar esta funo, o programa expTaylor_teste, mostrado na Figura 394, 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

Erro")

Figura 399: O programa expTaylor_teste.sce

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 400.
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 400: A funo expTaylor

Vamos primeiramente testar a funo para alguns valores positivos de x. Podemos ver na
Figura 401 que os resultados so muito bons, com diferenas 16 ordens de grandeza menores
que os valores calculados pelas duas funes.

11 - Algoritmos Numricos

254

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 401: Resultados de testes da funo expTaylor com x positivo

Mas o teste com valores negativos nos reserva surpresas desagradveis, como mostra a Figura
402. 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 402: 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 403: 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 403.
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

255

~4.3e007
15 ordens de
grandeza maior
que o resultado
correto

Figura 404: Grfico com valores absolutos dos termos da srie de Taylor para x == -20

A Figura 404 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

256

12 Complexidade de Problemas
Encontrar algoritmos eficientes um objetivo permanente dos programadores e cientistas da
computao. Para o problema da fatorao vimos um primeiro algoritmo com complexidade
(2 ), e um outro, superior, com complexidade (22 ). Para a pesquisa em um vetor
ordenado, ns vimos o algoritmo de pesquisa sequencial, (), muito inferior pesquisa
binria, (log ). 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?
A resposta no, o que em alguns casos fcil de ver. Para o problema de listar todas as
permutaes de um vetor de elementos, cuja sada formada por ! nmeros, claro que a
complexidade mnima (!); nenhum algoritmo seria capaz de reduzir isso. Para o problema
da ordenao, entretanto, a sada do mesmo tamanho da entrada, e ns veremos que
mesmo assim possvel determinar um limite
Em seguida, veremos uma classe de problemas que desafia os cientistas da computao. So
problemas de descrio geralmente simples, com sada de tamanho razovel, para os quais
ningum foi capaz seja de encontrar um algoritmo eficiente, seja de provar que no existem
algoritmos eficientes para resolv-los.
Prosseguindo nessa linha, veremos problemas indecidveis, isto , problemas para os quais
pode-se provar que no existe algoritmo capaz de resolver qualquer de suas instncias.

12 Complexidade de Problemas

257

Tpicos
1.
2.
3.
4.

Complexidade da Ordenao
O Problema do Caixeiro Viajante
As classes de algoritmos e
Problemas Indecidveis

Objetivos: Esperamos que voc, ao final deste mdulo, seja capaz de:

Explicar o limite terico de complexidade para algoritmos de ordenao por


comparaes
Descrever dificuldades prticas da aplicao de algoritmos com complexidade
exponencial
Explicar o problema do caixeiro viajante
Construir programas que resolvam por fora bruta problemas como o caixeiro viajante
Explicar o problema da satisfatibilidade
Descrever as classes de algoritmos e , e o problema =
Explicar o problema da correspondncia de Post
Explicar a noo de problema indecidvel

12 Complexidade de Problemas

258

12.2 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.

Comparao de elementos de
ndices 2 e 3 no vetor original

Resultado de
Comparao

ndices nos vetores originais


dos vetores ordenados

Figura 405: 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 405 mostra uma rvore de decises gerada pelo SelectSort, quando submetido a todas

12 Complexidade de Problemas

259

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 406: rvore de decises para o algoritmo da bolha

Figura 407: rvore de decises para o Quicksort

A Figura 406 mostra uma rvore de decises para o algoritmo da Bolha, e a Figura 407 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 408: rvore de decises para um algoritmo arbitrrio de ordenao por comparaes

12 Complexidade de Problemas

260

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 409 mostra
uma rvore binria, isto , uma rvore onde cada n tem no mximo 2 filhos.

Raiz

Folhas
no tm
filhos

Figura 409: 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 410 mostra as
profundidades dos ns da rvore da Figura 409.

p=0

p=1
p=2

p=3
Figura 410: 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.

12 Complexidade de Problemas

261

Figura 411: 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 411. 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 412.

log2 n

D=1

Figura 412: A soma dos logaritmos dos inteiros de 1 a n a soma de Riemann pela esquerda para log(n)

Podemos ento escrever

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.3 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
413. No existem estradas entre as cidades sem ligao no grafo.

12 Complexidade de Problemas

262
1
2

6
5

3
3
3

4
3
7

Figura 413: 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 414 voc pode ver como a escolha de um roteiro influencia a distncia
total.
1

1
2

6
5

1
2

6
2

3
4

3
3

3
7

3
3

D = 19

D = 22

D = 15

Figura 414: Algumas alternativas de roteiros para o caixeiro viajante

Um exame atento nos faz perceber que o roteiro mais direita na Figura 414 , dentre todos,
o de menor custo. Descobrir o roteiro timo fica bem mais complicado quando temos mais
cidades, como na Figura 415.
1
8
14

12 9

11
13

10

12

15

15

12

11
6

12

12
3

6
5

Figura 415: Um problema com 8 cidades

Temos muito mais alternativas a examinar; trs exemplos esto na Figura 416. 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.

12 Complexidade de Problemas

263

1
8
14

11

12 9

13

10

12

8
12

15

12

4
4

6
5

11

12 9

13

10

12

12
3

D = 81

14

3
4

11
6

12

12

15

15

11
12

14
3

15

6
5

11

12 9

13

10

12

15

15

12

11
6

12

12

D = 98

6
5

D = 64

Figura 416: Algumas alternativas de roteiros para o problema da Figura 415

Vamos tentar uma soluo direta. Devemos:


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

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 417).
Function p = permutations(A)
// gera uma matriz p onde
// cada linha uma permutao de A
Endfunction
Figura 417: 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.

12 Complexidade de Problemas

264

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 418 uma implementao direta deste


algoritmo.
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 418: A funo permutations

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.8 (pg. 167).
J podemos dar incio ao desenvolvimento do programa principal. A Figura 419 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 419: 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.

12 Complexidade de Problemas

265

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 420.

Figura 420 : Arquivo Distancias.txt com distncias entre as cidades mostradas na Figura 413

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 421, onde
est destacado o comando que faz as substituies.
// L a matriz de distncias
Dist = ...
fscanfMat(uigetfile("*.txt",pwd(),"Distncias"));
// Substitui -1 por %inf
Dist(Dist==-1) = %inf;
Figura 421: Leitura do arquivo com distncias

Para gerar as rotas e calcular seus custos, vamos usar a funo permutations da Figura
418, 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 422: Obteno de todas as rotas e clculo dos custos

Nos trechos de cdigo mostrados na Figura 422 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

266

// 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 423: O programa CaixeiroViajante.sce

A Figura 423 mostra o programa completo, que tambm usa as funes SelecionaMenor
(Figura 350, pgina 226) e PrintMatrix (Figura 351, pgina 227). Executando este
programa com o arquivo Distancias.txt (Figura 420), ns vemos que a melhor rota [1 2 3 5
4 1] com custo total = 15, mostrada na Figura 414.
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

267

Figura 424: 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 encontrada55
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.

12.4 Ordens de Complexidade e Reduo de Problemas

Figura 425: Comparao de tempos versus funo de complexidade56

A Figura 425 mostra o o tempo de execuo em funo do tamanho de problemas para


diversas funes de complexidade. Ali podemos ver como o tempo de execuo cresce de
forma dramtica com o tamanho da entrada para algoritmos com complexidade (2 ) e
(3 ).
55

Travelling salesman problem - Wikipedia, the free encyclopedia, acessado 11 de dezembro de 2012,
http://en.wikipedia.org/wiki/Travelling_salesman_problem#Computational_complexity.
56
M. R. Garey e D. S. Johnson, Computers and Intractability: A Guide to the Theory of NP-Completeness.

12 Complexidade de Problemas

268

Figura 426: Comparao de tamanhos de problemas que podem ser resolvidos em 1 hora por computadores de
diferentes velocidades57

Voc poderia pensar que, afinal, no ano que vem os computadores estaro mais rpidos, o que
viabilizaria a execuo de problemas que hoje demandam um tempo excessivo. Mas a Figura
426 mostra que o progresso conseguido com computadores 100 ou mesmo 1000 vezes mais
rpidos que os atuais muito pequeno para algoritmos com complexidade exponencial.
Os fatos mostrados nessas duas tabelas levaram os cientistas da computao a considerar
algoritmos cujo tempo de execuo cresce com alguma potncia de como bem
comportados, e dar aos algoritmos cujo tempo de execuo cresce mais rapidamente que
qualquer polinmio a qualificao de intratveis.
O conjunto de problemas de transformao de informao muito amplo, e para simplificar
um pouco a situao, cientistas de complexidade preferem trabalhar com problemas de
deciso, cuja resposta Sim ou No. O problema de deciso associado ao Caixeiro Viajante :
Dado um conjunto de cidades e as distncias entre elas, existe pelo menos uma rota
com custo menor que um oramento ?
A vantagem de um problema de deciso a possibilidade de definio de um problema
associado, que somente verifica uma soluo apresentada. Em muitos casos o problema de
verificao pode ter complexidade menor que o problema de deciso original. Por exemplo,
para o problema de deciso do Caixeiro Viajante, possvel verificar se uma dada rota tem
custo total menor que em tempo linear.
Algumas vezes possvel transformar um problema de deciso em outro problema , tal
que tem soluo se e somente se tem soluo. Ns chamamos essas transformaes de
redues: o problema reduzido ao problema . Adotando-se esse caminho, o trabalho
para se resolver a soma do trabalho da transformao com o trabalho para resolver o
problema . Aqui ns estamos interessados em transformaes que tenham complexidade
polinomial, pois se a transformao em si for intratvel, no ir nos ajudar muito.
Ns vamos apresentar um exemplo de reduo com um problema relacionado a grafos.
Grafos so conjuntos de vrtices e de arestas que unem vrtices. A Figura 427 apresenta dois
exemplos de representao grfica de grafos.

57

Ibidem.

12 Complexidade de Problemas

269

Figura 427: Exemplos de grafos

Dado um grafo, um circuito Hamiltoniano uma rota que percorre todos os vrtices do grafo,
sem passar duas vezes por nenhum deles. O problema de deciso que iremos estudar : dado
um grafo, existe um circuito Hamiltoniano?

Figura 428: Um circuito Hamiltoniano

A Figura 428 mostra um circuito Hamiltoniano para o grafo na parte direita da Figura 427; a
resposta seria Sim para este grafo. Um pouco de reflexo nos leva a concluir que no existe
circuito Hamiltoniano para o grafo na parte esquerda da Figura 427.
O problema do Circuito Hamiltoniano pode facilmente ser reduzido ao problema do Caixeiro
Viajante, adotanto as seguintes correspondncias:

A cada vrtice do grafo corresponde uma cidade


Para cada aresta entre dois vrtices, a distncia entre as cidades correspondentes
igual a 1
Se no existe aresta entre dois vrtices, a distncia entre as cidades correspondentes
igual a .

Com estas convenes, o problema de deciso do Caixeiro Viajante que resolve um problema
de Circuito Hamiltoniano :
Existe uma rota com custo total igual ao nmero de cidades?
Consideremos um problema de Circuito Hamiltoniano para o grafo da Figura 429.

12 Complexidade de Problemas

270

Figura 429: Existe um circuito Hamiltoniano para este grafo?

Para transform-lo em um problema do Caixeiro Viajante, o primeiro passo considerar cada


vrtice como uma cidade, e atribuir o valor 1 a cada aresta, como mostrado na Figura 430, que
tambm mostra uma soluo, que voc pode obter com o programa CaixeiroViajante.sce.

Figura 430: Problema do Caixeiro Viajante que resolve o problema do Circuito Hamiltoniano da Figura 429

12.5 P = NP?
Um problema de deciso muito importante sob aspectos prticos e tericos o da
satisfatibilidade de expresses booleanas. Dados

um conjunto de variveis booleanas 1 , 2 , , e


um conjunto de clusulas, que so expresses com dessas variveis, como (1 +
2 + 3 ,

o problema da satisfatibilidade (que tambm conhecido como SAT) consiste em procurar


saber se existe um conjunto de valores para 1 , 2 , , tal que o de todas as clusulas
tenha o valor ?
Para o problema abaixo (retirado de 58)
(1 + 2 + 3 ). (1 + 2 ). (2 + 3 ). (3 + 1 ). (1 + 2 + 3 )
se fizermos 1 = 2 = 3 = , todas as clusulas sero satisfeitas, com exceo da ltima.
Existiria uma atribuio de valores que satisfaria todas as clusulas? Podemos verificar isso
construindo uma tabela da verdade, como mostrado na Figura 431.

58

Sanjoy Dasgupta, Christos H. Papadimitriou, e Umesh Virkumar Vazirani, Algorithms (Boston: McGrawHill Higher Education, 2008).

12 Complexidade de Problemas

1
0
0
0
0
1
1
1
1

2
0
0
1
1
0
0
1
1

3
0
1
0
1
0
1
0
1

271

(1 + 2 + 3 ) (1 + 2 ) (2 + 3 ) (3 + 1 ) (1 + 2 + 3 )
0
1
1
1
1
1
1
0
1
1
1
0
1
1
1
1
0
1
1
1
1
1
1
0
1
1
1
0
1
1
1
1
1
0
1
1
1
1
1
0
Figura 431: Tabela da Verdade para expresso com trs variveis

Ali vemos que a expresso acima no satisfactvel, pois nenhuma combinao de valores
para as trs variveis faz com que todas as clusulas tenham o valor .
Este mtodo de soluo de um problema SAT por meio de uma tabela da verdade exige, no
mnimo, a enumerao de todas as possibilidades de valores para variveis, o que
claramente (2 ). Existem solues melhores? Sim, mas novamente, todas as solues
conhecidas so de complexidade exponencial. Repare ainda que se algum apresenta uma
atribuio de valores para as variveis dizendo que com esses valores todas as clusulas so
satisfeitas, isso facilmente verificvel, s necessitando da avaliao das clusulas para uma
linha da tabela da verdade.
O SAT e o problema de deciso do Caixeiro Viajante tm em comum as caractersticas:

S so conhecidas solues com complexidade exponencial, e


A verificao de uma proposta de soluo simples.

Outros problemas conhecidos esto na mesma situao, como o problema da Mochila, cuja
verso de otimizao consiste em encontrar quais objetos colocar em uma mochila, de forma a
maximizar o valor total dos objetos na mochila, e respeitando sua capacidade

Figura 432: Quais objetos devem ser colocados na mochila para se obter o maior peso total sem ultrapassar a
capacidade da mochila?

A percepo dessas similaridades levou os cientistas da Computao a definir duas classes de


complexidade para problemas de deciso:

A classe , formada pelos problemas que tm soluo polinomial, e


A classe , formada pelos problemas que tm soluo polinomial para a verificao
de solues, como o SAT e o Caixeiro Viajante.

12 Complexidade de Problemas

272

Claramente , pois se conseguimos produzir uma soluo em tempo polinomial,


conseguimos tambm verificar solues em tempo polinomial, pois a produo da soluo
em si uma verificao. Repare que no quer dizer No-Polinomial. O acrnimo vem de
Non-deterministic Polynomial, referindo-se a um artifcio terico utilizado para se ter o
problema de verificao resolvendo por pura sorte o problema de deciso.

Figura 433: Transformao Polinomial de um Problema

Suponha agora que dispomos de uma reduo polinomial que transforma o Problema 1 no
Problema 2. Neste caso,

Se for provado que toda soluo para o Problema 1 exponencial, o Problema 2 no


mnimo exponencial.
Se for encontrada uma soluo polinomial para o Problema 2, o Problema 1
polinomial.

Em 1971 Stephen Cook59 publicou um resultado muito forte sobre transformaes de


problemas, provando que todo problema da classe (isto , com verificao polinomial)
pode ser transformado em tempo polinomial para o problema SAT.

Figura 434: O Teorema de Cook

O teorema de Cook e a situao que prevalece at hoje, de no se saber se existe ou no uma


soluo polinomial para o SAT, leva a um dos problemas no resolvidos mais famosos da
Cincia da Computao, conhecido pela interrogao = ? Por um lado, se algum
problema em for exponencial (isto , se for provado que no existe soluo polinomial
para ele), como esse problema pode ser transformado no SAT, estar provado que o SAT
exponencial e que no pertence classe , e . Por outro lado, se algum encontrar um
algoritmo polinomial para o SAT, qualquer problema em ter complexidade polinomial, e
= .
Um problema da classe para o qual todo outro problema da classe pode ser reduzido
chamado de -completo. Pelo Teorema de Cook, o SAT um problema -completo.
Outros problemas -completos podem ser encontrados por transformaes polinomiais do
SAT, como o caso do problema do Circuito Hamiltoniano.

Figura 435: O problema do Circuito Hamiltoniano NP-completo

Ou seja, qualquer problema em pode ser transformado em tempo polinomial em um


problema SAT, e esse problema SAT pode ser transformado em tempo polinomial no problema
do Circuito Hamiltoniano. Ns podemos ento afirmar que, tal como acontece com o
problema SAT, se for possvel provar que no existe soluo polinomial para o Circuito
59

Stephen A. Cook, The Complexity of Theorem-proving Procedures, in Proceedings of the Third


Annual ACM Symposium on Theory of Computing, STOC 71 (New York, NY, USA: ACM, 1971), 151158,
doi:10.1145/800157.805047.

12 Complexidade de Problemas

273

Hamiltoniano, ento , e se por outro lado algum encontrar um algoritmo polinomial


para o Circuito Hamiltoniano, todo problema em pode ser resolvido em tempo polinomial,
e = .
Como ns vimos, um problema de Circuito Hamiltoniano pode ser transformado em um
problema de deciso do Caixeiro Viajante e, portanto, o problema de deciso do Caixeiro
Viajante tambm -completo.

Figura 436: Cadeias de problemas NP-completos

So conhecidos hoje em dia centenas de problemas -completos. Alguns deles, talvez os


mais conhecidos, tm as operaes de reduo descritas na referncia60.
Resumindo, se voc encontrar um algoritmo polinomial para qualquer problema completo, ou se voc encontrar um problema qualquer na classe para o qual voc consiga
provar que no existe nenhum algoritmo polinomial que o resolva, voc ter resolvido um dos
problemas mais famosos da Cincia da Computao, com direito ainda a um prmio61 de um
milho de dlares!

12.6 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

Tipo 2
0

Tipo 3
1

100

00

Figura 437: 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 438 mostra uma soluo para o problema proposto na Figura
437.

60

M. R. Garey e D. S. Johnson, Computers and Intractability: A Guide to the Theory of NP-Completeness.


The Millennium Prize Problems | Clay Mathematics Institute, acessado 15 de agosto de 2016,
http://www.claymath.org/millennium-problems/millennium-prize-problems.
61

12 Complexidade de Problemas

274

100

100

00

100

100

100

00

00

100

100

1001100100100
Figura 438: 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
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 439: O programa Post.sce

A Figura 439 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;

12 Complexidade de Problemas

275

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.

Figura 440: Tela do Bloco de Notas com um arquivo de tipos de domins para o problema de Post da Figura 437

Vamos comear pela leitura de um conjunto de tipos de domins. A Figura 440 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 441: A funo ReadPostProblem

A funo ReadPostProblem (Figura 441) 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.

12 Complexidade de Problemas

276

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 442: A funo WritePostProblem

A funo WritePostProblem (Figura 442) 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 443: A funo strPost

A Figura 443 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 444: A funo Sucessor

A funo Sucessor (Figura 444) 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 445 mostra alguns exemplos de uso desta
funo.

12 Complexidade de Problemas

277

-->Sucessor([],3)
ans =
1.
-->Sucessor([2 3 1],3)
ans =
2.
3.
2.
-->Sucessor([3 3 3],3)
ans =
1.
1.
1.
1.
Figura 445: Exemplos de uso da funo Sucessor

Finalmente temos a funo WritePostSolution (Figura 446) que imprime na tela a


soluo encontrada, em um formato tabular.
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 446: A funo WritePostSolution

J podemos testar o nosso programa para ver se encontramos a soluo da Figura 438.
Escolhendo como entrada o arquivo ProblemaPost.txt, vemos que o programa Post.sce
efetivamente resolve este problema, produzindo a sada mostrada na Figura 447.
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 447: Sada do programa Post.sce, alimentado com o arquivo da Figura 440.

Como voc j deve esperar, inferir desse primeiro sucesso que o nosso algoritmo resolve
qualquer problema de Post ingenuidade.
1000

01

00

101

001

Figura 448: 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 448 formada por 206 domins. Baseando-se em testes feitos pelo autor

12 Complexidade de Problemas

278

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 438 e da Figura 448, 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.
10

001

001

Figura 449: 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 449 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

280

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

281

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

282

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.3 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

283

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

284

ndice Remissivo
%eps, 136
%pi, 136
.sce, 139
acumulador, 99
lgebra Booleana, 53
algoritmo, 210
ALU, 101
ambiente Scilab, 133
AND, 54
Aritmtica matricial, 154
arquivo-programa, 139
rvore binria, 260
ASCII, 48
barramento, 96
Basic, 131
Binrios sem Sinal, 49
bit, 27
bloco ento, 146
bloco seno, 146
Blue Gene, 15
bootstrap, 115
bps, 34
C, 130
C++, 130
Carta de tempo, 93
chamadas da funo, 196
Cleve Moler, 132
clock, 102
Cobertura dos 1s, 69
Cobol, 130
Codificao com Deslocamento, 51
Comandos Aninhados, 181
comentrios, 141
comparao de binrios sem sinal, 83
comparador de 1 bit, 83
compilador, 130
Complemento de 2, 51
complexidade computacional, 211
complexidade linear, 219
condutor perfeito, 58
console do Scilab, 133
Construindo matrizes, 158
controlled buffer, 96
converso binrio-decimal, 50
converses A/D, 28
converses D/A, 28
Correo, 210

data width, 95
Demultiplexadores, 86
desenvolvimento top-down, 203
diretrio corrente, 140
dividir para conquistar, 239
Dvorak, 34
eco, 134
supresso do eco, 136
Eficincia, 210
else, 146
endereo, 97
endfunction, 197
escopo de variveis, 198
Especificao, 210
estouro, 72
Expresses booleanas, 54
expresses lgicas, 143
eye, 159
fatorao de nmeros inteiros, 211
flip-flop tipo D, 92
Flip-flops, 92
folhas, 260
Fortran, 129
fprintfMat, 187
fscanfMat, 187
funo recursiva, 205
function, 197
George Boole, 53
getf, 199
IBM PC, 14
IEEE 754, 52
if, 146
Indentao, 183
Informao, 24
Informao analgica, 24
informao digital, 24
input, 142
Integrao por Trapzios, 244
Internet, 22
interpretador, 132
isolante perfeito, 58
Java, 131
kiss principle, 221
lmpada de 7 segmentos, 80
largura de bits, 95
leg, 189
legibilidade, 182

ndice Remissivo
limites fisiolgicos, 34
linspace, 158
LISP, 131
mantissa, 52
MAR, 98
Matlab, 132
matriz identidade, 159
matriz inversa, 156
matriz transposta, 156
Matrizes, 149
Matrizes de Strings, 165
meia-soma, 69
Memrias, 35
Memrias secundrias, 37
Memrias tercirias, 37
Memory Addres Register. See MAR
merge, 229
mgetl, 186
Multiplexadores, 86
NAN, 53
NAND, 57
nomes de variveis, 134
NOR, 57
NOT, 54
ones, 159
operadores relacionais, 143
OR, 54
ordenao por Intercalao, 229
oscilador, 102
Ou Exclusivo. See XOR
overflow, 72
palavras, 97
Parmetros formais, 197
parmetros reais, 197
Pascal, 131
Pesquisa Binria, 219
Pesquisa Seqencial, 219
PHP, 131
pilha, 206
plot2d, 160
polgono, 189
Ponto Flutuante, 52
printf, 146
problema de transformao de
informao, 210
processador, 27
produto elemento a elemento, 155
produto matricial, 155
profundidade, 260
programa principal, 196
Prolog, 131

285
prova formal, 210
pwd, 186
Python, 131
raiz da rvore, 260
RAM, 35
rand, 159
rect, 189
registrador, 93
registrador circular, 103
Registradores, 35
retorno da funo, 196
RGB, 50
RoadRunner, 15
ROM, 97
sci, 199
Scilab, 132
SciPad, 139
seleo e troca, 224
Select Sort, 224
Sinal e Amplitude, 51
Sntese de Circuitos Combinatrios, 74
size, 151
soma cannica, 69
soma de Riemann, 244
soma-completa, 72
somador de n bits, 72
splitters, 95
Strings, 144
sub-circuito, 77
supercomputador, 16
tabela da verdade, 67
teclado Dvorak, 34
testes, 210
then, 146
timer, 212
Transistores, 57
Trocar os valores de duas variveis, 226
uigetfile, 185
unidade lgico-aritmtica, 101
vai-um, 71
Variveis, 134
variveis locais, 198
Variveis Lgicas, 147
varivel, 134
vem-um, 72
Vetores, 152
voltil, 35
volatilidade, 35
XOR, 61
xtitle, 189
zeros, 159

ndice Remissivo

286

Apndice A: A CPU Pipoca

287

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

Apndice A: A CPU Pipoca

288

Wolffdata. (n.d.). Wolffdata. Retrieved 2008, from ScilabStarter:


http://www.wolffdata.se/scilab/ScilabStarter.pdf
Referncias Zotero

Alan M. Turing. On Computable Numbers, with an Application to the


Entscheidungsproblem. Proceedings of the London Mathematical Society s242, no 1 (1937): 23065.
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.
Android (operating system) - Wikipedia, the free encyclopedia. Acessado 14 de
fevereiro de 2016. https://en.wikipedia.org/wiki/Android_(operating_system).
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.

Apndice A: A CPU Pipoca

289

Computer History Museum - Timeline of Computer History. Acessado 16 de fevereiro


de 2012. http://www.computerhistory.org/timeline/?year=1946.
Cook, Stephen A. The Complexity of Theorem-proving Procedures. In Proceedings of
the Third Annual ACM Symposium on Theory of Computing, 151158. STOC 71.
New York, NY, USA: ACM, 1971. doi:10.1145/800157.805047.
Dasgupta, Sanjoy, Christos H. Papadimitriou, e Umesh Virkumar Vazirani. Algorithms.
Boston: McGraw-Hill Higher Education, 2008.
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.
Interview with Bill Gates. Acessado 12 de fevereiro de 2016.
http://americanhistory.si.edu/comphist/gates.htm.
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.belllabs.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.
Magnetic-core memory - Wikipedia, the free encyclopedia. Acessado 12 de maro de
2011. http://en.wikipedia.org/wiki/Magnetic_core_memory.

Apndice A: A CPU Pipoca

290

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.].
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.
NCARs MSS exceeds 2 petabytes. Acessado 12 de agosto de 2011.
http://www.cisl.ucar.edu/news/04/fotoweek/0729.mss2pb.html.
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 Millennium Prize Problems | Clay Mathematics Institute. Acessado 15 de agosto
de 2016. http://www.claymath.org/millennium-problems/millennium-prizeproblems.
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.

Apndice A: A CPU Pipoca

Unicode - Wikipedia, the free encyclopedia. Acessado 19 de agosto de 2011.


http://en.wikipedia.org/wiki/Unicode.
VPL - Virtual Programming Lab. Acessado 8 de outubro de 2013.
http://vpl.dis.ulpgc.es/index.php.

291