<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>PT-BR on Jefferson Oliveira</title><link>https://jeffersonmourak.com/tags/pt-br/</link><description>Recent content in PT-BR on Jefferson Oliveira</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>All content provided by this website are my own opinons and beliefs and are distrubuted under the &lt;br/></copyright><lastBuildDate>Thu, 07 Aug 2025 10:29:04 -0300</lastBuildDate><atom:link href="https://jeffersonmourak.com/tags/pt-br/index.xml" rel="self" type="application/rss+xml"/><item><title>A Evolução da Escrita Digital - Do ASCII às Maravilhas do UTF-8</title><link>https://jeffersonmourak.com/blog/unicode/</link><pubDate>Thu, 07 Aug 2025 10:29:04 -0300</pubDate><guid>https://jeffersonmourak.com/blog/unicode/</guid><category domain="https://jeffersonmourak.com/tags/unicode/">Unicode</category><category domain="https://jeffersonmourak.com/tags/ascii/">ASCII</category><category domain="https://jeffersonmourak.com/tags/utf-8/">UTF-8</category><category>Data types</category><category>Data encoding</category><category>Character encoding</category><category>Binary</category><category>Shift JIS</category><category>Mojibake</category><category>Unicode Consortium</category><description>&lt;p>Já imaginou como computadores transformam letras, números e emojis em zeros e uns que eles possam entender? Assim como nós, humanos, atribuímos significados às letras do alfabeto, o computador faz o mesmo. Vamos explorar aqui dois dos padrões mais populares de codificação de texto.&lt;/p>
&lt;h3 id="ascii">ASCII&lt;/h3>
&lt;p>Desenvolvido na década de 1960, o ASCII (American Standard Code for Information Interchange) tem uma premissa bem simples: usando apenas 7 bits, consegue-se representar 127 números, deixando reservados os primeiros 32 números da sequência para comandos importantes de escrita. O restante é preenchido com letras, números e alguns caracteres de pontuação.&lt;/p></description><content:encoded><![CDATA[<p>Já imaginou como computadores transformam letras, números e emojis em zeros e uns que eles possam entender? Assim como nós, humanos, atribuímos significados às letras do alfabeto, o computador faz o mesmo. Vamos explorar aqui dois dos padrões mais populares de codificação de texto.</p>
<h3 id="ascii">ASCII</h3>
<p>Desenvolvido na década de 1960, o ASCII (American Standard Code for Information Interchange) tem uma premissa bem simples: usando apenas 7 bits, consegue-se representar 127 números, deixando reservados os primeiros 32 números da sequência para comandos importantes de escrita. O restante é preenchido com letras, números e alguns caracteres de pontuação.</p>
<p>As pessoas envolvidas no desenvolvimento do padrão fizeram de tal forma que a sequência do alfabeto pudesse ajudar na decodificação.</p>
<p>Por exemplo, o caractere do número &ldquo;0&rdquo; é o número <strong>48</strong>, que, representado em 7 bits, fica <code>011 0000</code>.
Assim como:</p>
<p>1 → <code>011 0001</code></p>
<p>2 → <code>011 0010</code></p>
<p>3 → <code>011 0011</code></p>
<p>Se notarem, os últimos 4 bits estão em sequência. Logo, para descobrir em ASCII qual o inteiro, é só subtrair 011 0000 (decimal: 48).</p>
<p>Da mesma forma, as letras do alfabeto: &ldquo;A&rdquo; é <strong>65</strong> → 100 0001 e o &ldquo;a&rdquo; é <strong>97</strong> → 110 0001. Com isso, era possível codificar todas as letras do alfabeto inglês 🇬🇧.</p>
<p><em>Interactive Observable notebook widget &mdash; <a href="https://jeffersonmourak.com/blog/unicode/">view it on the blog</a>.</em></p>
<!-- <p><em>Interactive Observable notebook: <code>unicode</code> (cells: <code>ascii</code>) &mdash; <a href="https://jeffersonmourak.com/blog/unicode/">view it on the blog</a>.</em></p>
 -->
<p><em>&hellip; enquanto isso no resto do mundo &hellip;</em></p>
<figure class="full-width">
  <img src="https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExZzNvcXQ4aTBpNGs5YWI3czdjeXBuaTU0dmw3eG44aWNxbTFxbzBieSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/3oz8xQBcUXftkrlmmc/giphy.gif" alt="Cena da série animada South Park" loading="lazy">
  <figcaption>Cena da série animada South Park</figcaption>
</figure><p>Como já era de imaginar, com o avanço da tecnologia e da capacidade dos computadores, cada país utilizou essa capacidade extra para codificar seus próprios caracteres. O Japão, por exemplo, nem o ASCII usou. Outros codificadores, como o Shift JIS, utilizavam múltiplos bytes, e com tudo isso gerou-se uma gigantesca incompatibilidade.</p>
<blockquote>
<p>Curiosidade:
No Japão, existe a palavra mojibake (文字化け), que significa &ldquo;caractere distorcido&rdquo;. Isso acontecia devido aos problemas de codificação entre todos os alfabetos japoneses e também o latino.</p></blockquote>
<p>Porém, mesmo com toda essa incompatibilidade durante os anos 1980 e 1990, quais eram as chances de uma empresa de Londres ter que mandar documentos constantemente para o Japão? Naquela época, a solução era simples: imprima e envie por fax!</p>
<figure class="full-width">
  <img src="https://media4.giphy.com/media/v1.Y2lkPTc5MGI3NjExY2IzdGtqeHVmemRsZ2cwYTliY2trM2Zla3M2bXZndHF1eHE5b2NkciZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/xT5LMKZ9tnioMLEjBe/giphy.gif" alt="Cena da série animada Os Simpsons" loading="lazy">
  <figcaption>Cena da série animada Os Simpsons</figcaption>
</figure><p>Então chegou a internet, e o que era ruim ficou ainda pior&hellip; Agora temos que lidar com documentos sendo enviados pela internet constantemente, e com o tempo foi formado o:</p>
<h2 id="unicode-consortium">Unicode Consortium</h2>
<p>E como em um evento que pode se chamar de milagre do bom senso, durante as últimas décadas, foi formado um padrão com 154.998 caracteres, que cobre toda e qualquer língua que você possa imaginar: árabe, japonês, cirílico, chinês, coreano e até hieróglifos egípcios.</p>
<p>O que eles fizeram de forma simplificada foi pegar centenas de milhares de números e atribuí-los a centenas de milhares de caracteres, ou seja, o número 35307 representará o caractere japonês 觫, o número 963 representará σ e assim por diante.</p>
<h3 id="utf-8">UTF-8</h3>
<p>Perfeito, agora nós temos centenas de milhares de números para representar todo e qualquer caractere, mas como vamos fazer isso com binário?</p>
<p>Para representar um número nessas proporções, vamos precisar de pelo menos 32 bits para representar qualquer número dessa magnitude, o que agora trouxe problemas para o alfabeto inglês, porque o Unicode é compatível com ASCII, ou seja, &ldquo;A&rdquo; ainda é <strong>65</strong> e &ldquo;a&rdquo; ainda é <strong>97</strong>. Mas quando olhamos para o binário de 32 bits desses números, agora usamos 4x mais espaço para representar os mesmos caracteres.</p>
<table>
  <thead>
      <tr>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td><strong>1</strong></td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td><strong>1</strong></td>
          <td></td>
          <td><strong>A</strong></td>
      </tr>
      <tr>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td><strong>1</strong></td>
          <td><strong>1</strong></td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td>0</td>
          <td><strong>1</strong></td>
          <td></td>
          <td><strong>a</strong></td>
      </tr>
  </tbody>
</table>
<p>Contando acima, há 25 zeros seguidos que estarão presentes em todo texto que utilizar caracteres latinos, e esse é só o primeiro dos nossos problemas. O segundo é que alguns sistemas antigos interpretam uma sequência de 8 zeros [<code>NULL</code>] como fim de caractere, o famoso <code>\0</code> do C.</p>
<p>Então entra o UTF-8. A primeira coisa é: se a letra tiver numeração abaixo de 127, então você representa exatamente igual ao ASCII.</p>
<p>Logo, o primeiro problema está resolvido: &ldquo;A&rdquo; ainda é <strong>65</strong> e cabe em 8 bits. <code>01000001</code>.</p>
<p>E para números maiores que 127? Para isso você vai quebrar seu binário em 2 bytes.</p>
<table>
  <thead>
      <tr>
          <th>1</th>
          <th>2</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>110xxxxx</code></td>
          <td><code>10xxxxxx</code></td>
      </tr>
  </tbody>
</table>
<p>No byte 1, você tem o cabeçalho <code>110</code>, que significa que esse caractere foi quebrado em 2 bytes.
No byte 2, você começa com o cabeçalho de continuidade <code>10</code>. Todos os outros bits restantes você vai preencher com o número que você quer representar.</p>
<p>Para calcular, é só remover os cabeçalhos, unir todos os bits e o número resultante é o caractere Unicode. Você pode fazer isso até 4096. Passou disso? Sem problemas! Usando o cabeçalho <code>1110</code> + 2 bytes, você tem 16 bits.</p>
<table>
  <thead>
      <tr>
          <th>1</th>
          <th>2</th>
          <th>3</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>1110xxxx</code></td>
          <td><code>10xxxxxx</code></td>
          <td><code>10xxxxxx</code></td>
      </tr>
  </tbody>
</table>
<p>Quer ir além? Tudo bem! O padrão suporta até o cabeçalho <code>1111110x</code> + 6 bytes de continuidade.</p>
<h3 id="codificando-utf-8">Codificando UTF-8</h3>
<p><em>Interactive Observable notebook widget &mdash; <a href="https://jeffersonmourak.com/blog/unicode/">view it on the blog</a>.</em></p>
<p>É incrível como esse padrão consegue entregar:</p>
<ul>
<li>
<p>É compatível com os sistemas anteriores;</p>
</li>
<li>
<p>Não gasta espaço;</p>
</li>
<li>
<p>E em nenhum momento na vida haverá 8 zeros seguidos em nenhuma parte de qualquer byte.</p>
</li>
</ul>
<p>Além disso, outra razão que o fez se tornar o padrão mundial hoje em dia é que, para se mover entre caracteres, se você não sabe onde está, é só procurar o próximo cabeçalho, não precisa de índice.</p>
<p>Já fazem alguns anos que o UTF-8 virou o padrão em toda comunicação pela internet, e o fato de hoje a pessoa japonesa média não precisar se preocupar com mojibake mais é por causa desse método genial de codificar texto.</p>
<h2 id="referencias">Referencias</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=MijmeoH9LT4">Characters, Symbols and the Unicode Miracle - Computerphile (YouTube)</a></li>
<li><a href="https://datatracker.ietf.org/doc/html/rfc3629">UTF-8, a transformation format of ISO 10646 - ietf.org</a></li>
<li><a href="https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/">The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) - Joel Spolsky</a></li>
</ul>
]]></content:encoded></item><item><title>A Tela é o Quadro - Desenhando fontes com matemática</title><link>https://jeffersonmourak.com/blog/font-rendering/</link><pubDate>Thu, 31 Jul 2025 10:29:04 -0300</pubDate><guid>https://jeffersonmourak.com/blog/font-rendering/</guid><category domain="https://jeffersonmourak.com/tags/font-rendering/">Font Rendering</category><category domain="https://jeffersonmourak.com/tags/font/">Font</category><category domain="https://jeffersonmourak.com/tags/computer-graphics/">Computer Graphics</category><description>&lt;p>No sábado, 26 de julho de 2025, apresentei uma palestra sobre renderização de fontes no Google I/O Extended Natal. Devido à correria do dia a dia, não consegui mostrar muitos exemplos práticos interativos. Este artigo serve justamente para isso: vamos explorar um pouco sobre como o texto que você está lendo é formado na sua tela.&lt;/p>
&lt;p>Para começar, falaremos sobre Bitmaps. Esta é a forma mais ingênua de desenhar fontes, pois um bitmap nada mais é do que uma imagem pronta. Abaixo, por exemplo, temos uma letra que ocupa um espaço de 6 pixels de altura por 6 pixels de largura.&lt;/p></description><content:encoded><![CDATA[<p>No sábado, 26 de julho de 2025, apresentei uma palestra sobre renderização de fontes no Google I/O Extended Natal. Devido à correria do dia a dia, não consegui mostrar muitos exemplos práticos interativos. Este artigo serve justamente para isso: vamos explorar um pouco sobre como o texto que você está lendo é formado na sua tela.</p>
<p>Para começar, falaremos sobre Bitmaps. Esta é a forma mais ingênua de desenhar fontes, pois um bitmap nada mais é do que uma imagem pronta. Abaixo, por exemplo, temos uma letra que ocupa um espaço de 6 pixels de altura por 6 pixels de largura.</p>
<p>No momento, você consegue visualizar facilmente porque o tamanho dos pixels está em 10 pixels. No entanto, se você alterar o tamanho para 1 pixel, verá que não é possível ler o que está na tela.&quot;</p>
<p><em>Interactive p5 widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<p>Como mostrado, o maior problema das fontes de bitmap é que elas não são escaláveis. Ou seja, para que possamos mudar o tamanho das fontes, teríamos que:</p>
<ul>
<li>
<p>Criar uma nova fonte com cada uma das letras desenhadas no novo tamanho.</p>
</li>
<li>
<p>Rasterizar a fonte em uma outra escala.</p>
</li>
</ul>
<p>Vamos ver o que acontece na segunda opção.</p>
<p>Essa é uma função simples de escala. Ela recebe como parâmetros os dados da letra que você quer desenhar e a escala na qual deseja aumentar.</p>
<p>Ela funciona simplesmente duplicando os pixels existentes tanto no eixo <em>X</em> quanto no <em>Y</em>.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">scaleGlyph</span> (<span style="color:#a6e22e">glyph</span>, <span style="color:#a6e22e">scale</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">newWidth</span> <span style="color:#f92672">=</span> Math.<span style="color:#a6e22e">ceil</span>(<span style="color:#a6e22e">glyph</span>.<span style="color:#a6e22e">width</span> <span style="color:#f92672">*</span> <span style="color:#a6e22e">scale</span>);
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">newHeight</span> <span style="color:#f92672">=</span> Math.<span style="color:#a6e22e">ceil</span>(<span style="color:#a6e22e">glyph</span>.<span style="color:#a6e22e">height</span> <span style="color:#f92672">*</span> <span style="color:#a6e22e">scale</span>);
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">newPixels</span> <span style="color:#f92672">=</span> Array.<span style="color:#a6e22e">from</span>({ <span style="color:#a6e22e">length</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">newHeight</span> }, () =&gt;
</span></span><span style="display:flex;"><span>    Array(<span style="color:#a6e22e">newWidth</span>).<span style="color:#a6e22e">fill</span>(<span style="color:#ae81ff">0</span>)
</span></span><span style="display:flex;"><span>  );
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">y</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">y</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">glyph</span>.<span style="color:#a6e22e">height</span>; <span style="color:#a6e22e">y</span><span style="color:#f92672">++</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">x</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">x</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">glyph</span>.<span style="color:#a6e22e">width</span>; <span style="color:#a6e22e">x</span><span style="color:#f92672">++</span>) {
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">value</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">glyph</span>.<span style="color:#a6e22e">pixels</span>[<span style="color:#a6e22e">y</span>][<span style="color:#a6e22e">x</span>];
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">newX</span> <span style="color:#f92672">=</span> Math.<span style="color:#a6e22e">floor</span>(<span style="color:#a6e22e">x</span> <span style="color:#f92672">*</span> <span style="color:#a6e22e">scale</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">newY</span> <span style="color:#f92672">=</span> Math.<span style="color:#a6e22e">floor</span>(<span style="color:#a6e22e">y</span> <span style="color:#f92672">*</span> <span style="color:#a6e22e">scale</span>);
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">dy</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">dy</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">scale</span>; <span style="color:#a6e22e">dy</span><span style="color:#f92672">++</span>) {
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> (<span style="color:#66d9ef">let</span> <span style="color:#a6e22e">dx</span> <span style="color:#f92672">=</span> <span style="color:#ae81ff">0</span>; <span style="color:#a6e22e">dx</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">scale</span>; <span style="color:#a6e22e">dx</span><span style="color:#f92672">++</span>) {
</span></span><span style="display:flex;"><span>          <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">newY</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">dy</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">newHeight</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">newX</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">dx</span> <span style="color:#f92672">&lt;</span> <span style="color:#a6e22e">newWidth</span>) {
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">newPixels</span>[<span style="color:#a6e22e">newY</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">dy</span>][<span style="color:#a6e22e">newX</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">dx</span>] <span style="color:#f92672">=</span> <span style="color:#a6e22e">value</span>;
</span></span><span style="display:flex;"><span>          }
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>      }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">width</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">newWidth</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">height</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">newHeight</span>,
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">pixels</span><span style="color:#f92672">:</span> <span style="color:#a6e22e">newPixels</span>,
</span></span><span style="display:flex;"><span>  };
</span></span><span style="display:flex;"><span>};
</span></span></code></pre></div><p>O problema desse tipo de escala é que as fontes acabam obtendo um aspecto de bloco, o que traz a sensação de uma imagem com baixa resolução.</p>
<p>Outra forma é aplicando uma escala utilizando interpolação linear. Essa técnica consiste em tirar uma média de todos os pontos originais ao redor, em vez de simplesmente copiar o bloco inteiro, repetindo cegamente o que há no pixel. No entanto, isso agora resulta em um aspecto de imagem borrada, e essa característica se acentua quanto maior a diferença entre o tamanho original e o tamanho final.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">lerp</span>(<span style="color:#a6e22e">x0</span>, <span style="color:#a6e22e">v0</span>, <span style="color:#a6e22e">x1</span>, <span style="color:#a6e22e">v1</span>, <span style="color:#a6e22e">x</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (<span style="color:#a6e22e">x0</span> <span style="color:#f92672">===</span> <span style="color:#a6e22e">x1</span>) {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">v0</span>;
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">v0</span> <span style="color:#f92672">+</span> (<span style="color:#a6e22e">v1</span> <span style="color:#f92672">-</span> <span style="color:#a6e22e">v0</span>) <span style="color:#f92672">*</span> ((<span style="color:#a6e22e">x</span> <span style="color:#f92672">-</span> <span style="color:#a6e22e">x0</span>) <span style="color:#f92672">/</span> (<span style="color:#a6e22e">x1</span> <span style="color:#f92672">-</span> <span style="color:#a6e22e">x0</span>));
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-javascript" data-lang="javascript"><span style="display:flex;"><span><span style="color:#66d9ef">function</span> <span style="color:#a6e22e">bilinearInterpolate</span>(<span style="color:#a6e22e">Q11</span>, <span style="color:#a6e22e">Q21</span>, <span style="color:#a6e22e">Q12</span>, <span style="color:#a6e22e">Q22</span>, <span style="color:#a6e22e">x</span>, <span style="color:#a6e22e">y</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> (
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Q11</span>.<span style="color:#a6e22e">x</span> <span style="color:#f92672">!==</span> <span style="color:#a6e22e">Q12</span>.<span style="color:#a6e22e">x</span> <span style="color:#f92672">||</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Q21</span>.<span style="color:#a6e22e">x</span> <span style="color:#f92672">!==</span> <span style="color:#a6e22e">Q22</span>.<span style="color:#a6e22e">x</span> <span style="color:#f92672">||</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Q11</span>.<span style="color:#a6e22e">y</span> <span style="color:#f92672">!==</span> <span style="color:#a6e22e">Q21</span>.<span style="color:#a6e22e">y</span> <span style="color:#f92672">||</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Q12</span>.<span style="color:#a6e22e">y</span> <span style="color:#f92672">!==</span> <span style="color:#a6e22e">Q22</span>.<span style="color:#a6e22e">y</span>
</span></span><span style="display:flex;"><span>  ) {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">console</span>.<span style="color:#a6e22e">error</span>(
</span></span><span style="display:flex;"><span>      <span style="color:#e6db74">&#34;Error: The provided points do not form a proper rectangle for bilinear interpolation.&#34;</span>
</span></span><span style="display:flex;"><span>    );
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">x1</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">Q11</span>.<span style="color:#a6e22e">x</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">x2</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">Q21</span>.<span style="color:#a6e22e">x</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">y1</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">Q11</span>.<span style="color:#a6e22e">y</span>;
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">y2</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">Q12</span>.<span style="color:#a6e22e">y</span>;
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">R1</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">lerp</span>(<span style="color:#a6e22e">x1</span>, <span style="color:#a6e22e">Q11</span>.<span style="color:#a6e22e">value</span>, <span style="color:#a6e22e">x2</span>, <span style="color:#a6e22e">Q21</span>.<span style="color:#a6e22e">value</span>, <span style="color:#a6e22e">x</span>);
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">R2</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">lerp</span>(<span style="color:#a6e22e">x1</span>, <span style="color:#a6e22e">Q12</span>.<span style="color:#a6e22e">value</span>, <span style="color:#a6e22e">x2</span>, <span style="color:#a6e22e">Q22</span>.<span style="color:#a6e22e">value</span>, <span style="color:#a6e22e">x</span>);
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">const</span> <span style="color:#a6e22e">P</span> <span style="color:#f92672">=</span> <span style="color:#a6e22e">lerp</span>(<span style="color:#a6e22e">y1</span>, <span style="color:#a6e22e">R1</span>, <span style="color:#a6e22e">y2</span>, <span style="color:#a6e22e">R2</span>, <span style="color:#a6e22e">y</span>);
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">P</span>;
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Com isso temos os exemplos a baixo,</p>
<p><em>Interactive p5 widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<h2 id="como-utilizar-uma-só-fonte-para-vários-tamanhos">Como utilizar uma só fonte para vários tamanhos?</h2>
<p>Na matemática, existem equações que desenham um gráfico na tela. Os exemplos mais comuns são:</p>
<h3 id="função-quadrática">Função quadrática</h3>
<p><em>Interactive Observable notebook widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<h3 id="função-inversa-multiplicativa">Função inversa multiplicativa</h3>
<p><em>Interactive Observable notebook widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<h3 id="manipulando-a-curva">Manipulando a curva</h3>
<p>Para mover nossas equações, podemos somar um valor qualquer após o resultado da exponenciação e, assim, movemos nossa equação no eixo <em>Y</em>.</p>
<p><em>Interactive Observable notebook widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<p>Para mover nossa equação na horizontal, adicionamos esse valor antes de elevá-lo ao quadrado.</p>
<p><em>Interactive Observable notebook widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<p>Então, já temos uma maneira de representar nossas curvas utilizando equações matemáticas.</p>
<p>Mas antes de desenharmos, vamos aprender sobre mais uma coisa.</p>
<h2 id="curvas-de-bézier">Curvas de Bézier</h2>
<p>Ela é uma curva polinomial expressa como a interpolação linear entre alguns pontos representativos, chamados de pontos de controle.</p>
<p>No exemplo abaixo, temos 3 pontos: <em>P0</em>, <em>P1</em> e <em>P2</em>, onde <em>P0</em> e <em>P2</em> são os pontos representativos e <em>P1</em> é o ponto de controle, você pode mover os exemplos abaixo e ver o resultado.</p>
<p><em>Interactive p5 widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<h3 id="desenhando-uma-letra-com-vetores">Desenhando uma letra com vetores</h3>
<p><em>Interactive p5 widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<p>Com o conceito de Bézier, fica até intuitivo como podemos desenhar uma letra usando matemática: basta organizar pontos em sequência e misturar linhas retas com curvas de Bézier, fazendo com que o <em>P2</em> de uma termine exatamente onde começa o <em>P0</em> da outra.</p>
<p>Aliás, uma reta também pode ser feita com Bézier; basta alinhar todos os pontos. Dessa forma, fica ainda mais claro como a interpolação atua na curva de Bézier.</p>
<p><em>Interactive p5 widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<p>Com isso, já podemos agora pensar em como transformar isso em um bitmap. Para fazer isso, precisamos primeiramente rasterizar essa fonte, começando por traduzir as curvas de Bézier em linhas compatíveis com a resolução da tela. Isso acontece porque a tela do computador é uma matriz de pixels; logo, precisamos transformar curvas em pixels legíveis ao olho humano.</p>
<p><em>Interactive p5 widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<p>Feito isso, a última coisa que se precisa é preencher a letra. Essa parte pode ser feita por um processo chamado scanline, que consiste em lançar um raio e contar quantas vezes esse raio vai tocar uma das paredes da letra. Se o número de toques for par, o pixel está representado fora da letra; se for ímpar, ele está dentro.</p>
<div class="figure-row">
  <figure>
      <img src="outter-intersect.png" alt="2 intersections with the letter">
      <figcaption>2 Interseções com a letra</figcaption>
  </figure>
  <figure>
      <img src="in-vs-out.png" alt="2 and 3 intersections with the letter">
      <figcaption>2 e 3 Interseções com a letra</figcaption>
  </figure>
  <figure>
      <img src="full-example.png" alt="2, 3, and 4 intersections with the letter">
      <figcaption>2, 3 e 4 Interseções com a letra</figcaption>
  </figure>
</div>
<p>Perceba que, no exemplo da letra &lsquo;O&rsquo;, há uma falha na renderização. Ela está aí de propósito: o processo de renderizar fontes é complicado e cheio de edge cases que só aumentam quanto mais aprofundamos no assunto.</p>
<p>O que quero demonstrar com essa falha é que, além de contar quantas vezes sua linha corta a letra, deve-se também estar ciente se a linha está cortando ela mesma novamente.</p>
<p><em>Interactive p5 widget &mdash; <a href="https://jeffersonmourak.com/blog/font-rendering/">view it on the blog</a>.</em></p>
<p>Bem, e com isso, concluímos esta etapa do processo de renderização das fontes. Daqui a uns dias, vou publicar outros dois artigos sobre o tema para complementar o assunto da palestra. Eles serão sobre Unicode e Text Shaping.</p>
<p>Muito obrigado, e até a próxima! 😊</p>
<figure>
  <img src="https://media2.giphy.com/media/v1.Y2lkPTc5MGI3NjExdXM1amV6MWJ0eWs4cjY3OHJhNXNwZ2o1ZWkzYnVrNjMxZTlwNmlpcyZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/1jkVi22T6iUrQJUNqk/giphy.gif" alt="Jimmy Fallon escorregando e dando tchau" loading="lazy">
  <figcaption>Jimmy Fallon escorregando e dando tchau</figcaption>
</figure><h2 id="referencias">Referencias</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=qcMuyHzhvpI">A Brief look at Text Rendering - VoxelRifts (YouTube)</a></li>
<li><a href="https://www.youtube.com/watch?v=SO83KQuuZvg">Coding Adventure: Rendering Text -Sebastian Lague (YouTube)</a></li>
<li><a href="https://www.youtube.com/watch?v=LaYPoMPRSlk">The Math Behind Font Rasterization | How it Works - GamesWithGame (YouTube)</a></li>
<li><a href="https://faultlore.com/blah/text-hates-you/">Text Rendering Hates You - Aria Desires</a></li>
<li><a href="https://github.com/Chlumsky/msdfgen">Multi-channel signed distance field generator - Viktor Chlumský[Valve] (GitHub)</a></li>
<li><a href="https://github.com/harfbuzz/harfbuzz">Harfbuzz[Google] - (GitHub)</a></li>
</ul>
<!--
  p5.js is loaded here as a plain global so the inline observable:notebook
  cells in this post (the `p5(sketch)` wrapper at id="0") can reference
  `window.p5` directly without going through Observable's `require()`. A
  non-deferred <script> blocks parsing where it sits, so by the time the
  notebook's module bundle runs (module scripts are deferred until the
  document finishes parsing), `window.p5` is guaranteed to exist.
-->
<script src="https://cdn.jsdelivr.net/npm/p5@1.11.3/lib/p5.min.js"></script>
]]></content:encoded></item><item><title>Lembra de mim?</title><link>https://jeffersonmourak.com/blog/memory/</link><pubDate>Sun, 19 Jan 2025 08:27:04 -0300</pubDate><guid>https://jeffersonmourak.com/blog/memory/</guid><category domain="https://jeffersonmourak.com/tags/cpu/">CPU</category><category domain="https://jeffersonmourak.com/tags/memory/">Memory</category><category domain="https://jeffersonmourak.com/tags/combinational/">Combinational</category><category domain="https://jeffersonmourak.com/tags/sequential/">Sequential</category><description>&lt;blockquote>
&lt;p>Olá todo mundo, este é o terceiro artigo na série sobre computadores, e também o último com esse cabeçalho aqui, pois daqui para a frente é recomendado que você já tenha lido os dois artigos anteriores:&lt;/p>
&lt;ul>
&lt;li>&lt;a href="https://jeffersonmourak.com/blog/logic-gates/">Portas lógicas&lt;/a>.&lt;/li>
&lt;li>&lt;a href="https://jeffersonmourak.com/blog/the-binary/">Prazer, Binário.&lt;/a>.&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;p>Nos artigos anteriores, nós vimos como portas lógicas podem ser usadas para fazer comparações e também calcular operações aritméticas, porém ainda não vimos como o computador pode guardar uma informação ao longo do tempo.&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>Olá todo mundo, este é o terceiro artigo na série sobre computadores, e também o último com esse cabeçalho aqui, pois daqui para a frente é recomendado que você já tenha lido os dois artigos anteriores:</p>
<ul>
<li><a href="https://jeffersonmourak.com/blog/logic-gates/">Portas lógicas</a>.</li>
<li><a href="https://jeffersonmourak.com/blog/the-binary/">Prazer, Binário.</a>.</li>
</ul></blockquote>
<p>Nos artigos anteriores, nós vimos como portas lógicas podem ser usadas para fazer comparações e também calcular operações aritméticas, porém ainda não vimos como o computador pode guardar uma informação ao longo do tempo.</p>
<p>Outra coisa que também iremos fazer aqui é categorizar cada tipo de chip: os que foram mostrados anteriormente são <em><strong>combinacionais</strong></em>, o que significa que eles não precisam de nada além de sinais nas suas entradas para poder computar um resultado, mas existem também os <em><strong>sequenciais</strong></em>. A diferença entre eles é que o sequencial depende não só dos sinais das entradas, mas também do valor anteriormente processado.</p>
<p>Um jeito muito prático de usar portas lógicas para guardar informações é usando um chip chamado de <em><strong>flip-flop</strong></em>, que está representado abaixo. Ele contém 2 entradas: a de cima <code>set</code> e a de baixo <code>reset</code> (você pode clicar no circuito abaixo para interagir com eles).</p>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/memory/">view it on the blog</a>.</em></p>
<pre><code>╭───────╮     ╭───╮           ╭───╮     ╭───╮
│ reset ├○───▶┤NOT├○╮     ╭──▶┤   │ ╭──▶┤LED│
╰───────╯     ╰───╯ │     │   │AND├○●   ╰───╯
                    ╰─────┼──▶┤   │ │        
                          │   ╰───╯ │        
            ╭─────────────┼─────────╯        
╭─────╮     │ ╭─────────╮ │                  
│ set ├○╮   ╰▶┤         │ │                  
╰─────╯ │     │[or:_or_]├○╯                  
        ╰────▶┤         │                    
              ╰─────────╯                    </code></pre>
<p>Se parar para analisar, é bem simples: seguindo a trilha do <code>set</code>, verá que há duas portas lógicas no caminho, uma <code>OR</code> e uma <code>AND</code>. Uma das entradas da porta <code>OR</code> está ligada com o resultado da <code>AND</code> lá no fim do chip. Essa combinação faz com que, quando temos <strong>0</strong> e é nos dado um valor <strong>1</strong>, a porta <code>OR</code> vai resultar em <strong>1</strong>, e a <code>AND</code> também.</p>
<p>Porém, quando removemos o sinal do <code>set</code>, o valor que foi anteriormente colocado é persistido porque agora o <code>OR</code> está mantendo o estado que mantém o <code>AND</code> também no estado anterior. Problema resolvido, certo? Não! Perceba que nosso circuito agora está travado, pois não há como sair desse estado a não ser que o <code>AND</code> passe a ter um outro valor, e é para isso que serve a porta <code>reset</code>: ela está ligada a um <code>NOT</code>, ou seja, enquanto ela estiver desligada (0), o seu resultado vai ser 1 (ligado), e vice-versa.</p>
<p>Uma evolução que podemos fazer no <em><strong>flip-flop</strong></em> é transformá-lo em um <em><strong>Registrador</strong></em>. No registrador, podemos escolher se é ou não a hora de ler o nosso sinal e guardá-lo, e subsequentemente reescrevê-lo, e tudo isso ao nosso bel-prazer. Existem muitas formas de atingir esse chip, então vou usar a implementação demonstrada pelo <a href="https://www.youtube.com/watch?v=I0-izyq6q5s">Sebastian Lague</a>.</p>
<p>Nela, a gente só precisa adicionar mais 3 portas lógicas e pronto!</p>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/memory/">view it on the blog</a>.</em></p>
<pre><code>╭──────╮        ╭───╮     ╭───╮     ╭───╮     ╭───╮     ╭───╮     ╭───╮     ╭───╮     ╭───╮
│ data ├○──●───▶┤   │  ╭─▶┤NOT├○┬──▶┤NOT├○───▶┤   │ ╭──▶┤NOT├○╮ ╭▶┤   │ ╭──▶┤NOT├○●──▶┤LED│
╰──────╯   │    │AND├○─╯  ╰───╯ │   ╰───╯     │AND├○╯   ╰───╯ │ │ │AND├○╯   ╰───╯ │   ╰───╯
           │╭──▶┤   │           │           ╭▶┤   │           ╰─┼▶┤   │           │        
           ││   ╰───╯           │           │ ╰───╯             │ ╰───╯           │        
           ││                   ├───────────┼───────────────────╯                 │        
╭─────────╮││   ╭───╮     ╭───╮ │           │                                     │        
│ enabled ├○┼──▶┤NOT├○───▶┤   │ │           ╰─────────────────────────────────────╯        
╰─────────╯ │   ╰───╯     │AND├○╯                                                          
            ╰────────────▶┤   │                                                            
                          ╰───╯                                                            </code></pre>
<p>Se a gente destrinchar um pouco, o que acontece é o seguinte: a entrada superior, que agora chamaremos de <code>data</code>, só será salva no <em><strong>flip-flop</strong></em> quando a entrada inferior, que também mudou o nome, agora se chama <code>enabled</code>. Ou seja, em vez de usar duas entradas, uma para salvar e outra para apagar, essa combinação de <code>AND</code>s e <code>NOT</code> escolhe qual operação será feita.</p>
<ul>
<li>Se <code>data</code> = 1 e <code>enabled</code> = 1, então é a mesma coisa que ligar a entrada <code>set</code> do <em><strong>flip-flop</strong></em>.</li>
<li>Se <code>data</code> = 0 e <code>enabled</code> = 1, então é a mesma coisa que ligar a entrada <code>reset</code> do <em><strong>flip-flop</strong></em>.
Perceba que o <code>enabled</code> precisa sempre estar ativado para que possa salvar o sinal que foi colocado em <code>data</code>.</li>
</ul>
<p>Uma outra coisa que podemos fazer é pegar inspiração no artigo anterior, que no final a gente aprende que, se juntarmos vários Adders, nós podemos fazer contas com múltiplos dígitos. Na memória é do mesmo jeito: juntando vários registradores, você pode fornecer uma entrada para cada <code>data</code> e compartilhar o sinal do <code>enabled</code>, e assim você pode salvar os valores de um número binário inteiro.</p>
<p>Por enquanto, a gente se despede por aqui, até a próxima 😄</p>
<figure>
  <img src="https://media2.giphy.com/media/v1.Y2lkPTc5MGI3NjExOXlucmJmbW5mZWp4MGRpOXhpZWZwczdma2xmemIxZGVjZ3hiZG5sciZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/m9eG1qVjvN56H0MXt8/giphy.gif" alt="Xauzinho!" loading="lazy">
  <figcaption>Xauzinho!</figcaption>
</figure><h2 id="referências">Referências</h2>
<ul>
<li><a href="https://www.youtube.com/watch?v=I0-izyq6q5s">How Do Computers Remember? (YouTube)</a></li>
<li><a href="https://www.youtube.com/watch?v=KM0DdEaY5sY">SR latch (YouTube)</a></li>
<li><a href="https://www.youtube.com/watch?v=peCh_859q7Q">D latch</a></li>
<li><a href="https://www.youtube.com/watch?v=HjneAhCy2N4">HOW TRANSISTORS RUN CODE? (YouTube)</a></li>
<li><a href="https://www.nand2tetris.org/">From Nand to Tetris</a></li>
</ul>
]]></content:encoded></item><item><title>Prazer, Binário.</title><link>https://jeffersonmourak.com/blog/the-binary/</link><pubDate>Sat, 14 Dec 2024 08:27:04 -0300</pubDate><guid>https://jeffersonmourak.com/blog/the-binary/</guid><category domain="https://jeffersonmourak.com/tags/cpu/">CPU</category><category domain="https://jeffersonmourak.com/tags/binary/">Binary</category><category domain="https://jeffersonmourak.com/tags/numeric-systems/">Numeric-Systems</category><category>Computação</category><category>Binário</category><description>&lt;blockquote>
&lt;p>Olá pessoas dessa internet, para quem está chegando aqui agora, este é o segundo artigo de
uma série que estou fazendo para falar sobre os fundamentos da computação, recomendo ler o
primeiro sobre &lt;a href="https://jeffersonmourak.com/blog/logic-gates/">portas lógicas&lt;/a>.
E para quem já leu o primeiro artigo, dá um pulinho lá porque eu fiz uma revisão no artigo, recomendo bastante dar uma olhada 😊&lt;/p>&lt;/blockquote>
&lt;p>Vamos nos aprofundar um pouco mais e explorar alguns conceitos de matemática e também da história humana.&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>Olá pessoas dessa internet, para quem está chegando aqui agora, este é o segundo artigo de
uma série que estou fazendo para falar sobre os fundamentos da computação, recomendo ler o
primeiro sobre <a href="https://jeffersonmourak.com/blog/logic-gates/">portas lógicas</a>.
E para quem já leu o primeiro artigo, dá um pulinho lá porque eu fiz uma revisão no artigo, recomendo bastante dar uma olhada 😊</p></blockquote>
<p>Vamos nos aprofundar um pouco mais e explorar alguns conceitos de matemática e também da história humana.</p>
<p>A matemática veio da necessidade de contar e medir da raça humana – quantos animais a Maria cuida, quantos dias até o próximo solstício&hellip; Com o tempo e a expansão humana, povos antigos criaram vários sistemas de numeração para o seu dia a dia. Jogos como <em>Grand Theft Auto V</em>, <em>Call of Duty: Black Ops III</em>, <em>Dragon Quest XI</em> são exemplos de uso do sistema numeral que os romanos usavam, e o <em>I Ching</em>, um antigo texto chinês, tem raízes em representações binárias.</p>
<p>Porém, não somente as antigas civilizações usavam outros sistemas numéricos. As horas de um dia são divididas entre 12 horas do período da manhã e 12 horas do período da tarde, ou uma dúzia de ovos. Na língua francesa ainda existem resquícios de um sistema com base vigesimal (20), por exemplo, o número 80 se diz <em>quatre-vingts</em> (quatro vintes), e um dos mais recentes é o Braille, que também tem raízes em representações binárias.</p>
<p>Nos dias atuais, utilizamos a representação decimal, e o motivo é bem simples: a média de dedos em mãos humanas são incríveis 10 dedos, sendo assim fica mais fácil contar usando somente as mãos.</p>
<h2 id="----">☝️ + ☝️ = ✌️</h2>
<p>Essa representação em base 10 é posicional, ou seja, a posição em que os dígitos são &ldquo;desenhados&rdquo; muda a quantidade que se está representando. <em>70</em> representa dez vezes mais que <em>07</em>, daí vem o ditado popular &ldquo;zero à esquerda&rdquo;. Na escola, aprendemos as casas decimais – <em>unidades</em>, <em>dezenas</em>, <em>centenas</em>&hellip; Elas servem para representar qual é a posição desse dígito.</p>
<table>
  <thead>
      <tr>
          <th style="text-align: center">Dezena</th>
          <th>Unidade</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: center">    7   </td>
          <td>0     </td>
      </tr>
      <tr>
          <td style="text-align: center">    0   </td>
          <td>7     </td>
      </tr>
  </tbody>
</table>
<p>E em cima dessa ordem existe uma fórmula matemática que converte um número de qualquer base para decimal. Para facilitar:</p>
<ul>
<li><strong>Dígito</strong>: Símbolo que representa uma quantidade única.
  <em>Ex.: 1, 2, 3, 4, 5, 6, 7, 8, 9, 0</em></li>
<li><strong>Número</strong>: Dígitos organizados em ordem de <em><strong>posição</strong></em>.
  <em>Ex.: 10, 144, 999, 42, 37, <code>0x8A6C</code>, <code>0b101010</code></em></li>
<li><strong>Base</strong>: Quantidade máxima de dígitos que pode ser representada.
  <em>Ex.: binário (<code>0b</code>) 2, decimal 10, hexadecimal (<code>0x</code>)</em></li>
<li><strong>Índice</strong>: A magnitude do dígito na posição.
  _Ex.: 10, o 1 em 10 tem <em>Índice 1</em> e o 0 tem <em>Índice 0</em> (é meio contraintuitivo, mas faz sentido).
  Em outras palavras, o índice é a posição da direita para a esquerda, começando em 0.</li>
</ul>
<p>A fórmula é bem simples: <em><strong>(d)ígito × (b)ase<sup>(i)ndice</sup></strong></em>. No exemplo que estamos fazendo, esta é a fórmula para converter 70 em decimal&hellip; para 70 em decimal. <strong>7 × 10<sup>1</sup> + 0 × 10<sup>0</sup> = 70</strong></p>
<p><em>Interactive binary counter widget (base 10, 3 digits) &mdash; <a href="https://jeffersonmourak.com/blog/the-binary/">view it on the blog</a>.</em></p>

<p>Quando falamos de números dessa forma, fica mais fácil representar o binário, que nada mais é que a quantidade que pode ser representada pela fórmula <em><strong>d × 2<sup>i</sup></strong></em>.</p>
<p><em>Interactive binary counter widget (base 2, 6 digits) &mdash; <a href="https://jeffersonmourak.com/blog/the-binary/">view it on the blog</a>.</em></p>

<p>E essa forma de representar quantidades também pode ser manipulada com operações matemáticas. A adição 25 + 17 é resolvida de modo parecido com isso.</p>
<pre tabindex="0"><code>1
2 5
1 7
--- +
4 2
</code></pre><p>No exemplo acima, temos alguns elementos que precisam ser destacados:</p>
<ol>
<li>Um <em>dígito</em> só pode ser somado com outro <em>dígito</em> que estiver no mesmo <em>índice</em>.</li>
<li>Quando a soma não puder ser representada com apenas um dígito, o menor índice é mantido como <em>resultado</em>, e o <em>resto</em> é enviado para o próximo índice.</li>
<li>O <em>resultado</em> de uma soma será sempre a soma dos <em><strong>dígitos</strong></em> do <em><strong>índice</strong></em> + o <em><strong>resto</strong></em> que veio do <em><strong>dígito</strong></em> no <em><strong>índice</strong></em> anterior.</li>
</ol>
<p>Com esses mesmos passos, podemos aplicar a soma em qualquer base.</p>
<pre tabindex="0"><code>    1 1 1       |  1      |  
1 0 0 0 1 1     |  2 5    |  1 9
0 0 0 1 1 1     |  1 7    |  1 1
------------ +  |  --- +  |  --- +
1 0 1 0 1 0     |  4 2    |  2 A 
</code></pre><figure>
  <img src="./hand.jpeg" alt="Cálculo de 25 &#43; 17 em bases Binária, Decimal e Hexadecimal" loading="lazy">
  <figcaption>Cálculo de 25 + 17 em bases Binária, Decimal e Hexadecimal</figcaption>
</figure><p><em>Interactive binary counter widget (base 2, 6 digits) &mdash; <a href="https://jeffersonmourak.com/blog/the-binary/">view it on the blog</a>.</em></p>

<p>Agora que já nos conhecemos, como podemos fazer para o computador nos conhecer também?</p>
<h2 id="brincando-de-tradução">Brincando de tradução</h2>
<p>Lembrando do <a href="https://jeffersonmourak.com/blog/logic-gates/">artigo anterior</a>, vamos isolar a soma de dois dígitos em tabelas. A primeira, vamos olhar para o resultado apenas. Temos esta tabela que se assemelha muito com a tabela da porta OR, exceto por essa pequena mudança no final.</p>
<div style="display: flex; gap: 16px;">
<span>
<table>
<tr><td colspan="3">Resultado</td></tr>
<tr>
 <td>?</td>
 <td>0</td>
 <td>1</td>
</tr>
<tr>
 <td>0</td>
 <td>0</td>
 <td>1</td>
</tr>
<tr>
 <td>1</td>
 <td>1</td>
 <td>0</td>
</tr>
</table>
</span>
<span>
<table>
<tr><td colspan="3">OR</td></tr>
<tr>
 <td>∨</td>
 <td>0</td>
 <td>1</td>
</tr>
<tr>
 <td>0</td>
 <td>0</td>
 <td>1</td>
</tr>
<tr>
 <td>1</td>
 <td>1</td>
 <td>1</td>
</tr>
</table>
</span>
</div>
<p>Para isso, podemos combinar o resultado das portas que já vimos anteriormente em um só circuito chamado &ldquo;OU Exclusivo&rdquo; ou &ldquo;XOR&rdquo;.</p>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/the-binary/">view it on the blog</a>.</em></p>
<pre><code>╭───╮     ╭─────────────╮     ╭───╮     ╭───╮
│ a ├○●●─▶┤             │╭───▶┤   │ ╭──▶┤LED│
╰───╯ ││  │[nand:_nand_]├○╮   │AND├○╯   ╰───╯
      │●─▶┤             ││╰──▶┤   │          
      ││  ╰─────────────╯│    ╰───╯          
      ││                 │                   
╭───╮ ││  ╭─────────╮    │                   
│ b ├○●╰─▶┤         │    │                   
╰───╯ │   │[or:_or_]├○───╯                   
      ╰──▶┤         │                        
          ╰─────────╯                        </code></pre>
<p>Agora, vamos olhar também para a tabela do resto da nossa soma e se percebe que é uma cópia exata da porta AND.</p>
<div style="display: flex; gap: 16px;">
<span>
<table>
<tr><td colspan="3">Resto</td></tr>
<tr>
 <td>?</td>
 <td>0</td>
 <td>1</td>
</tr>
<tr>
 <td>0</td>
 <td>0</td>
 <td>0</td>
</tr>
<tr>
 <td>1</td>
 <td>0</td>
 <td>1</td>
</tr>
</table>
</span>
<span>
<table>
<tr><td colspan="3">AND</td></tr>
<tr>
 <td>∧</td>
 <td>0</td>
 <td>1</td>
</tr>
<tr>
 <td>0</td>
 <td>0</td>
 <td>0</td>
</tr>
<tr>
 <td>1</td>
 <td>0</td>
 <td>1</td>
</tr>
</table>
</span>
</div>
<p>E assim como o Capitão Planeta, &ldquo;Pela união dos seus poderes&rdquo;, nós vamos conseguir fazer a operação de soma de dois dígitos em binário, e esse componente é chamado de &ldquo;Somador&rdquo; ou &ldquo;Adder&rdquo;.</p>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/the-binary/">view it on the blog</a>.</em></p>
<pre><code>╭───╮        ╭───╮               ╭───╮               ╭─────────╮     ╭───╮
│ a ├○●●────▶┤   │           ╭──▶┤   │ ╭────────────▶┤         │ ╭──▶┤LED│
╰───╯ ││     │AND├○╮         │   │AND├○╯             │[or:_or_]├○╯   ╰───╯
      │●────▶┤   │ │         │ ╭▶┤   │             ╭▶┤         │          
      ││     ╰───╯ │         │ │ ╰───╯             │ ╰─────────╯          
      ││           ╰─────────┼─┼───────────────────╯                      
╭───╮ ││     ╭─────────────╮ │ │ ╭─────────────╮                     ╭───╮
│ b ├○●╰────▶┤             │ ●─┼▶┤             │ ╭──────────────────▶┤LED│
╰───╯ │      │[xor:_xor_1_]├○● │ │[xor:_xor_2_]├○╯                   ╰───╯
      ╰─────▶┤             │   ●▶┤             │                          
             ╰─────────────╯   │ ╰─────────────╯                          
                               │                                          
╭──────╮                       │                                          
│ c_in ├○──────────────────────●                                          
╰──────╯                                                                  </code></pre>
<p>Com essa combinação de portas lógicas, um computador já consegue fazer as incríveis somas de: <code>0 + 0</code>, <code>1 + 0</code>, <code>0 + 1</code>, <code>1 + 1</code>, mas, além disso, ele consegue também dizer quanto que houve de resto da soma. E quando combinados vários ADDERs, a gente consegue fazer uma soma de números mais complexos como o 42, mas essa nós vamos ver no próximo artigo.</p>
<p>Por hoje é só isso, pessoal.</p>
<figure>
  <img src="https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExaXg4ZHNiMjVkMG1nY3M3NjRhaDI5cmFoNWtmaHVxNDBweGV5ZjdwOCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/xUPOqo6E1XvWXwlCyQ/giphy.gif" alt="Isso é tudo pessoal!" loading="lazy">
  <figcaption>Isso é tudo pessoal!</figcaption>
</figure><h2 id="referências">Referências</h2>
<ul>
<li><a href="https://pt.wikipedia.org/wiki/%C3%81lgebra_booliana">A brief history of numerical systems (Youtube)</a></li>
<li><a href="https://en.wikipedia.org/wiki/Numeral_system">Numeral system (Wikipédia)</a></li>
<li><a href="https://pt.wikipedia.org/wiki/Sistema_de_numera%C3%A7%C3%A3o">Sistema de numeração (Wikipédia)</a></li>
<li><a href="https://www.youtube.com/watch?v=QZwneRb-zqA">Exploring How Computers Work (YouTube)</a></li>
<li><a href="https://www.youtube.com/watch?v=sTu3LwpF6XI">Making logic gates from transistors (YouTube)</a></li>
<li><a href="https://www.youtube.com/watch?v=HjneAhCy2N4">HOW TRANSISTORS RUN CODE? (YouTube)</a></li>
<li><a href="https://www.nand2tetris.org/">From Nand to Tetris</a></li>
</ul>
]]></content:encoded></item><item><title>Portas lógicas</title><link>https://jeffersonmourak.com/blog/logic-gates/</link><pubDate>Thu, 07 Nov 2024 08:27:04 -0300</pubDate><guid>https://jeffersonmourak.com/blog/logic-gates/</guid><category domain="https://jeffersonmourak.com/tags/cpu/">CPU</category><category domain="https://jeffersonmourak.com/tags/logic-gates/">Logic Gates</category><category>Portas lógicas</category><category>Computação</category><description>&lt;blockquote>
&lt;p>Revisado [11/12/2024]&lt;/p>
&lt;p>Oi pessoal, então tive que fazer umas mudanças aqui no post pra adicionar alguns widgets
interativos, e aproveitei para dar um pouco mais de contexto ao conteúdo.&lt;/p>&lt;/blockquote>
&lt;p>Olá, este é o primeiro artigo de uma série sobre os fundamentos da computação. A ideia é demonstrar de forma simples e prática como este dispositivo transforma zeros e uns em praticamente qualquer coisa, o funcionamento das CPUs e outros assuntos interessantes. Então, para começar, o primeiro conceito que temos que aprender é o de portas lógicas: elas são a base de toda a computação, com elas podemos fazer certas operações que recebem como entrada um ou mais valores e terão outro valor como resultado.&lt;/p></description><content:encoded><![CDATA[<blockquote>
<p>Revisado [11/12/2024]</p>
<p>Oi pessoal, então tive que fazer umas mudanças aqui no post pra adicionar alguns widgets
interativos, e aproveitei para dar um pouco mais de contexto ao conteúdo.</p></blockquote>
<p>Olá, este é o primeiro artigo de uma série sobre os fundamentos da computação. A ideia é demonstrar de forma simples e prática como este dispositivo transforma zeros e uns em praticamente qualquer coisa, o funcionamento das CPUs e outros assuntos interessantes. Então, para começar, o primeiro conceito que temos que aprender é o de portas lógicas: elas são a base de toda a computação, com elas podemos fazer certas operações que recebem como entrada um ou mais valores e terão outro valor como resultado.</p>
<p>Mas o que são esses valores? O número 42? O nome da minha mãe? Esses “valores” são energia, mais especificamente a presença e ausência dela. Como foi falado na introdução, computadores funcionam utilizando dígitos binários, ou seja, essas máquinas só entendem 0 e 1 ou “Tem energia” e “Não tem energia”. No entanto, não iremos chamar esses zeros e uns de energia, para o computador eles são sinais.</p>
<p>Quando sinais são combinados e/ou comparados, nós chamamos de operação lógica, por exemplo.</p>
<p>“[Sons de harpa de inicio de história]”</p>
<p>Um dia você contrata uma empresa de elétrica para instalar dois interruptores em um corredor da sua casa, mas, por um erro de desenho, a instalação acaba ficando da seguinte forma: o fio passa pelo primeiro interruptor (vamos chamar de interruptor A), vai direto para o segundo interruptor (B para os íntimos) e, em seguida, sai para a lâmpada.</p>
<figure>
  <img src="./CPUImageFrame1.png" alt="" loading="lazy">
</figure><p>Reparou que a lâmpada só acende se os dois interruptores estiverem ligados ao mesmo tempo? Se qualquer um deles for desligado, a luz apaga na hora! Pois é, essa atrocidade da elétrica residencial pode ser explicada, na matemática, a partir de um de seus ramos chamado de álgebra booleana, e nela podemos demonstrar isso com uma tabela:</p>
<table>
  <thead>
      <tr>
          <th style="text-align: center">∧</th>
          <th style="text-align: center">0</th>
          <th style="text-align: center">1</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: center">0</td>
          <td style="text-align: center">0</td>
          <td style="text-align: center">0</td>
      </tr>
      <tr>
          <td style="text-align: center">1</td>
          <td style="text-align: center">0</td>
          <td style="text-align: center">1</td>
      </tr>
  </tbody>
</table>
<p>Escrevendo isso de outro modo fica assim:</p>
<table>
  <thead>
      <tr>
          <th style="text-align: left">∧</th>
          <th style="text-align: left">A desligado</th>
          <th style="text-align: left">A ligado</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: left">B desligado</td>
          <td style="text-align: left">Luz apagada</td>
          <td style="text-align: left">Luz apagada</td>
      </tr>
      <tr>
          <td style="text-align: left">B ligado</td>
          <td style="text-align: left">Luz apagada</td>
          <td style="text-align: left">Luz acesa</td>
      </tr>
  </tbody>
</table>
<p>Se você percebeu bem, agora temos um jeito de representar o que queremos que aconteça com dois interruptores e uma lâmpada, e esse exemplo mostrado acima é a primeira porta lógica que estamos conhecendo, o AND ou Conjunção, e essa tabela, demonstrada acima de formas diferentes, se chama Tabela-Verdade.</p>
<p>Ok, mas e a luz da minha casa? Como que vai ficar? Eu preciso que a luz acenda quando o A OU B estiverem ligados. Como que faz isso?</p>
<p>A resposta está na própria pergunta! 😉 Vamos precisar de uma outra porta lógica, a OR ou Disjunção, e para entender como ela funciona, vamos usar uma tabela-verdade que se encaixe nessas condições:</p>
<table>
  <thead>
      <tr>
          <th style="text-align: center">?</th>
          <th style="text-align: center">0</th>
          <th style="text-align: center">1</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: center">0</td>
          <td style="text-align: center">0</td>
          <td style="text-align: center">1</td>
      </tr>
      <tr>
          <td style="text-align: center">1</td>
          <td style="text-align: center">1</td>
          <td style="text-align: center">1</td>
      </tr>
  </tbody>
</table>
<p>Mas antes de falar da OR, vamos dar uma olhada na porta NOT (ou Negação). Ela é bem simples, mas vai ser importante mais pra frente.</p>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/logic-gates/">view it on the blog</a>.</em></p>
<pre><code>╭───╮     ╭───╮     ╭───╮
│ a ├○───▶┤NOT├○───▶┤LED│
╰───╯     ╰───╯     ╰───╯</code></pre>
<p>E se escrevermos ela numa tabela verdade teremos isso aqui:</p>
<table>
  <thead>
      <tr>
          <th style="text-align: center">¬</th>
          <th style="text-align: center">0</th>
          <th style="text-align: center">1</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: center"></td>
          <td style="text-align: center">1</td>
          <td style="text-align: center">0</td>
      </tr>
  </tbody>
</table>
<p>Então, vamos fazer uma pausa e revisar o que a gente já sabe. Primeiro, as operações e como representá-las numa tabela. Para simplificar, vamos transformar essas operações em símbolos. Toda vez que nos referirmos ao AND, este será o símbolo:</p>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/logic-gates/">view it on the blog</a>.</em></p>
<pre><code>╭───╮     ╭───╮     ╭───╮
│ a ├○───▶┤   │ ╭──▶┤LED│
╰───╯     │AND├○╯   ╰───╯
       ╭─▶┤   │          
       │  ╰───╯          
       │                 
╭───╮  │                 
│ b ├○─╯                 
╰───╯                    </code></pre>
<p>e o NOT:</p>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/logic-gates/">view it on the blog</a>.</em></p>
<pre><code>╭───╮     ╭───╮     ╭───╮
│ a ├○───▶┤NOT├○───▶┤LED│
╰───╯     ╰───╯     ╰───╯</code></pre>
<p>Com essas duas operações lógicas (AND e NOT), já podemos combinar seus resultados e criar uma terceira porta lógica: a NAND (ou Not AND).</p>
<p>Ela pode ser representada assim:</p>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/logic-gates/">view it on the blog</a>.</em></p>
<pre><code>╭───╮     ╭─────────────╮     ╭───╮
│ a ├○───▶┤             │ ╭──▶┤LED│
╰───╯     │[nand:_nand_]├○╯   ╰───╯
       ╭─▶┤             │          
       │  ╰─────────────╯          
       │                           
╭───╮  │                           
│ b ├○─╯                           
╰───╯                              </code></pre>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/logic-gates/">view it on the blog</a>.</em></p>
<pre><code>╭───╮     ╭───╮     ╭───╮     ╭───╮
│ a ├○───▶┤   │ ╭──▶┤NOT├○───▶┤LED│
╰───╯     │AND├○╯   ╰───╯     ╰───╯
       ╭─▶┤   │                    
       │  ╰───╯                    
       │                           
╭───╮  │                           
│ b ├○─╯                           
╰───╯                              </code></pre>
<p>A tabela-verdade dela é idêntica à do AND, porém com os resultados invertidos.</p>
<table>
  <thead>
      <tr>
          <th style="text-align: center">¬∧</th>
          <th style="text-align: center">0</th>
          <th style="text-align: center">1</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: center">0</td>
          <td style="text-align: center">1</td>
          <td style="text-align: center">1</td>
      </tr>
      <tr>
          <td style="text-align: center">1</td>
          <td style="text-align: center">1</td>
          <td style="text-align: center">0</td>
      </tr>
  </tbody>
</table>
<p>Seguindo essa mesma lógica de combinar portas, podemos usar uma porta NAND e inverter a entrada de cada interruptor com um NOT. Assim, teremos o seguinte:</p>
<p><em>Interactive circ widget &mdash; <a href="https://jeffersonmourak.com/blog/logic-gates/">view it on the blog</a>.</em></p>
<pre><code>╭───╮     ╭───╮     ╭─────────────╮     ╭───╮
│ a ├○───▶┤NOT├○───▶┤             │ ╭──▶┤LED│
╰───╯     ╰───╯     │[nand:_nand_]├○╯   ╰───╯
                 ╭─▶┤             │          
                 │  ╰─────────────╯          
                 │                           
╭───╮     ╭───╮  │                           
│ b ├○───▶┤NOT├○─╯                           
╰───╯     ╰───╯                              </code></pre>
<p>Analisando o diagrama acima, vemos que, quando os dois interruptores estiverem desligados, ambos os sinais serão invertidos pelo NOT, e o NAND vai resultar em ¬∧(1, 1) = 0. Ou seja, com ambos desligados, a lâmpada apaga. Mas o que acontece quando temos ¬∧(1, 0) ou ¬∧(0, 1)? Para descobrir, vamos analisar a tabela-verdade:</p>
<table>
  <thead>
      <tr>
          <th style="text-align: center">∨</th>
          <th style="text-align: center">0</th>
          <th style="text-align: center">1</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td style="text-align: center">0</td>
          <td style="text-align: center">0</td>
          <td style="text-align: center">1</td>
      </tr>
      <tr>
          <td style="text-align: center">1</td>
          <td style="text-align: center">1</td>
          <td style="text-align: center">1</td>
      </tr>
  </tbody>
</table>
<figure>
  <img src="https://media1.giphy.com/media/v1.Y2lkPTc5MGI3NjExa2F3aTZ5Z2FhajUxem51aG5oYzBwYW1jdHI3NGswMzZzd3duMTh3biZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/n9h61thJkq6Xe/giphy.gif" alt="Eu acho que vi um gatinho!" loading="lazy">
  <figcaption>Eu acho que vi um gatinho!</figcaption>
</figure><p>Mas espera um pouco, eu tenho a impressão de que eu já vi essa tabela antes? Sim! Essa é a porta lógica OR que estávamos procurando. Uma viagem e tanto, não é? Agora que já sabemos como consertar a fiação da lâmpada, podemos dar uma paradinha aqui. Este é apenas o primeiro artigo de uma série sobre computadores. Mais para frente, vamos abordar outras portas lógicas e outros conceitos da computação.</p>
<h2 id="referências">Referências</h2>
<ul>
<li><a href="https://pt.wikipedia.org/wiki/%C3%81lgebra_booliana">Álgebra booliana (Wikipédia)</a></li>
<li><a href="https://en.wikipedia.org/wiki/Boolean_algebra">Boolean Algebra (Wikipédia)</a></li>
<li><a href="https://pt.wikipedia.org/wiki/Tabela-verdade">Tabela-verdade  (Wikipédia)</a></li>
<li><a href="https://www.youtube.com/watch?v=QZwneRb-zqA">Exploring How Computers Work (YouTube)</a></li>
<li><a href="https://www.youtube.com/watch?v=sTu3LwpF6XI">Making logic gates from transistors (YouTube)</a></li>
<li><a href="https://www.youtube.com/watch?v=HjneAhCy2N4">HOW TRANSISTORS RUN CODE? (YouTube)</a></li>
</ul>
]]></content:encoded></item></channel></rss>