Publicado em Hardware, Low level, Tecnologia

Androides sonham com ovelhas elétricas?

Esse é o título em português do livro de Philip K. Dick que inspirou o roteiro do filme “Blade Runner” de Ridley Scott, o mesmo cara que dirigiu “Alien”. Ainda não assistiu? Meu Deus, como pode? Vai lá, é urgente!

Androides são computadores que imitam humanos em sua aparência externa e comportamento, mas internamente são essa ensamblagem maluca de chips, fios, sensores, alavancas e servomotores que aparece nos filmes. Não sei se os computadores vão conseguir alguma vez virar autoconscientes ou sonhar com ovelhas elétricas, mas se eles chegarem nesse patamar, as ovelhas deverão ser bem diferentes daqueles bichinhos que nós conhecemos.

1 + 1 = 10

Por enquanto, computadores funcionam com energia elétrica e representam a informação em formato digital, é dizer, sequências de apenas dois valores que podem ser, por exemplo, duas voltagens (de 0 a 2 volts um valor, e de 3 a 5 volts um outro). As ovelhas elétricas nos sonhos androidianos seriam algum tipo de fluxo elétrico onde esses dois valores (voltagens) se alternariam em sequências oníricas.

Nós, humanos, quando pensamos em informação digital criamos uma abstração para representar esses dois valores ou estados físicos: 1 e 0, um e zero. Essa aqui é uma breve introdução à forma em que computadores poderiam representar (e sonhar) ovelhas.

Você tem 10010110 dólares na conta!

Mais fácil do que representar ovelhas é representar números inteiros positivos. A gente adora coisas fáceis:

0 = 0
1 = 1
2 = ... e agora?

Aí complicou… Se só temos dois símbolos, como podemos representar mais do que duas coisas? Bom, apenas temos 10 dedos nas mãos mas a gente se vira para contar uma dúzia. Lembra que o nosso sistema de numeração decimal é posicional?:

12   =  10 + 2        =  1 x 101 + 2 x 100
451  =  400 + 50 + 1  =  4 x 102 + 5 x 101 + 1 x 100

O que aplica a um sistema de 10 símbolos, também aplica a um outro com apenas 2:

10   =  1 x 21 + 0 x 20  =  2
1101 =  1 x 23 + 1 x 22 + 0 x 21 + 1 x 20  =  13

Melhor não sair gastando a toa, que os 10010110 dólares binários do cabeçalho são apenas 150 dólares. Se pelo menos eles fossem bitcoins

Quanto custa um nibble?

Seu computador é de 32-bit ou 64-bit, mas o Arduino UNO é de 8-bit. Essa é a quantidade de uns e zeros que o processador ou o microcontrolador (µc) conseguem manejar a cada ciclo de relógio. Assim como nós, simples mortais, falamos em dezenas, centenas, ou trilhões, nossos primos androides fazem as contas em: bits, bytes, megas, etc.

1 bit      = 0 ou 1
1 nibble   = 4 bits
1 byte     = 8 bits
1 word     = 16 bits
1 dword    = 32 bits (double word)
1 qword    = 64 bits (quad word)
1 Megabyte = 1024 bytes     (210 bytes)
1 Gigabyte = 1024 Megabytes (220 bytes)
1 Terabyte = 1024 Gigabytes (230 bytes)

Por exemplo, uma memória RAM de 4GB tem capacidade para armazenar 33.554.432 zeros ou uns:

4 (GB) x 220 (bytes) x 8 (bits) = 4 x 1.048.576 x 8 = 33.554.432 bits

7 + 1 = -8

Acredite, essa conta pode acontecer em Androilândia. Eu falei que as ovelhas deles não eram que nem as nossas.

Com 4 dígitos eu e você podemos representar 10 mil (104) elementos: [0..9999]. Nossos émulos, com 4 bits, apenas poderiam representar 16 (24) elementos:

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111

Com essas 16 combinações poderiam significar os números inteiros positivos (unsigned) [0..15]:

0 → 0000     8 → 1000
1 → 0001     9 → 1001
2 → 0010    10 → 1010
3 → 0011    11 → 1011
4 → 0100    12 → 1100
5 → 0101    13 → 1101
6 → 0110    14 → 1110
7 → 0111    15 → 1111

Ou poderiam significar os inteiros [-8..7] (signed). Considerando positivos os números que começam em 0 e negativos aqueles que começam em 1:

0 → 0000     ? → 1000
1 → 0001    -1 → 1001
2 → 0010    -2 → 1010
3 → 0011    -3 → 1011
4 → 0100    -4 → 1100
5 → 0101    -5 → 1101
6 → 0110    -6 → 1110
7 → 0111    -7 → 1111

O problema aqui é o que fazer com o 1000. Representa o -8? Ou o zero negativo? Ou a gente descarta e não usa? Além disso, o que acontece quando operamos com esses números?:

-2 + 2 = 0          1010
                  + 0010
                    ----
                    1100 (-4)

Isso não parece muito certo…
Os caras expertos que constroem androides optaram por uma outra alternativa, o complemento a 2:

0 → 0000    -8 → 1000
1 → 0001    -7 → 1001
2 → 0010    -6 → 1010
3 → 0011    -5 → 1011
4 → 0100    -4 → 1100
5 → 0101    -3 → 1101
6 → 0110    -2 → 1110
7 → 0111    -1 → 1111

Agora sim, o -8 faz parte de uma sequência mais lógica e, mais importante, as contas batem:

-2 + 2 = 0          1110
                  + 0010
                    ----
                    0000 (0)

Batem, sempre que não cair fora dos 4 bits (ou o tamanho que a gente tenha definido): 7 + 7 = 14, mas… cadê o 14? Não pode ser representado com apenas 4 bits (signed). Lembra que o “High Order Bit” (o primeiro à esquerda) representa o signo.
E batem também, se não misturarmos as formas de representação (signed and unsigned):

7 + 1 = 8           0111
                  + 0001
                    ----
                    1000 (8 ou -8)

O resultado dessa operação depende de se estamos representando os números sem signo [0..15] ou com signo [-8..7].

As energias negativas

Para se obter a forma negativa de um inteiro positivo no complemento a 2 realizamos duas operações: primeiro invertemos (~) cada bit, a continuação, somamos 1:

~5 + 1 = -5
                ~(0101) = 1010  →  1010
                                 + 0001
                                   ---- 
                                   1011 (-5)

Dica

A linguagem de programação Python conta com um intérprete iterativo muito bacana que, entre muitas outras coisas, permite fazer conversões e operar com representações numéricas decimal, binária, octal e hexadecimal; podemos fazer bitwise operations e usar uma livraria matemática bem completa. Python é open source e multiplataforma, você pode baixar e usar livremente, ainda que seja como calculadora científica super vitaminada:

>>> bin(150)
'0b10010110'
>>> int(0b10010110)
150
>>> hex(0b10010110)
'0x96'
>>> oct(0x96)
'0o226'
>>> 0o226 + 0x96 + 0b10010110 + 150
600
>>> ~ 0b10010110
-151

Post data

Espero ter podido ajudar, ainda que pouco, na compreensão de alguns conceitos básicos da representação interna que o computador faz das nossas ideias. As coisas ficam ainda mais complexas quando começamos a mexer com números racionais (ponto flutuante). Quer um conselho, não mexa com esses caras se não quer problemas. Se não tiver alternativa, pratica algo de jiu jitsu antes enfrentá-los, esses androides são verdadeiros “replicantes”.

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google

Você está comentando utilizando sua conta Google. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.