Archive for September 2013

Multiplicação em Binário

September 09, 2013

Okay, para entender multiplicação em binário é necessário primeiro entender adição e subtração em binário, e sobre isso eu já escrevi no post anterior.  Se você tem duvidas sobre esse assunto, recomendo ler e entender sobre isso antes de mergulhar aqui.

Primeiro vale definir que aqui usaremos 10 bits, como os dez dedos das mãos e daremos a esses bits os nomes de Bit1, Bt2, até Bit10, sendo o Bit1 o bit mais à direita, e o Bit10 o mais à esquerda.  O Bit1 terá o valor de 1, o Bit2 terá valor 2, o Bit3 terá valor 4, e assim por diante, dobrando o valor, até que o Bit10 terá o valor 512. Todos os bits levantados somarão o valor 1023, todos os bits baixados = 0.

BIT10  BIT9  BIT8  BIT7  BIT6  BIT5  BIT4  BIT3  BIT2  BIT1
512    256   128   64    32    16     8     4     2     1

Para iniciar, vou rever aqui com vocês como se faz uma multiplicação tradicional em decimal no papel e lápis.

Vamos multiplicar 25 x 76

        2  5
        7  6
        –  -     Multiplica-se Cruzado
        3  0     = Cinco vezes Seis
     3  5  -     = Cinco vezes Sete
     1  2  -     = Dois vezes Seis
  1  4  -  -     = Dois vezes Sete
  –  -  -  -     Soma-se os resultados individuais
  1  9  0  0     Resultado

Okay, explicarei de outra maneira.

Veja, em decimal os numeros vão de zero a 9, portanto para a mesma posição (digito) podem ocorrer dez variações do valor.  Eu quero dizer que ao ter o número 35, para a mesma posição do “5″ pode-se ter de 30 a 39, portanto dez variações no dígito das unidades.

Em binário não é assim, é mais simples, pois binário só entender ZERO e UM, portanto para cada posição de bit, só teremos duas possíveis variações de valor.  O binário  ”10″ (2 em decimal) pode variar o bit mais a direita entre zero e um, portanto a “outra” combinação seria “11″ (3 em decimal) e só.

Então vejamos a outra maneira de multiplicar em decimal que imediatamente vai fazer você entender a multiplicação em binário.

325 x 76  (em decimal)

Okay, sem multiplicar, só somando.  Primeiro vamos somar 5 vezes o número 76, e depois 2 vezes o número 760, e 3 vezes 7600.   Mas de onde vieram o zero do 760 e os dois zeros do 7600? vieram do Vinte  e do Trezentos, olhe bem, 325 é Trezentos + Vinte + Cinco.   Deslocar o 76 uma vez para a esquerda e transforma-lo em 760 e soma-lo 2 vezes, é o mesmo que somar vinte vezes o 76.

Uma outra forma de entender é pensar assim:  Trezentos e Vinte e Cinco é 300 + 20 + 5.   Observe os zeros do trezentos e o zero do vinte.

Tanto faz multiplicar 325 x 76, ou (300 x 76) + (20 x 76) + (5 x 76), certo?
e também é o mesmo que passar os zeros para o 76, e ficaria assim:
(3 x 7600) + (2 x 760) + (5 x 76), correto?

Então seria assim:

Percebeu que eu sempre uso o valor “76″ para as unidades (5), “760″ para as dezenas (2), e “7699″ para as centenas (3)?

Ai está o truque da multiplicação em binário.  Acima, em decimal, terá que somar tantas vezes quanto for o número da unidade, dezena, centena, milhar, etc, e pode ir de zero a nove.   Em binário só existem duas combinações, zero e um.  Portanto, se for zero não soma, se for um soma e pronto, acabou para aquela posição de bit.  Abaixo entenderá com mais detalhes.

Treze em decimal é  0x0D em hexadecimal, ou 0b1101 em binário

Cinco em decimal é 0×05 em hexadecimal, ou 0b0101 em binário

Então vamos multiplicar 0x0D x 0×05

Assim como na multiplicação em decimal, note que as multiplicações individuais do cruzado se deslocam para a esquerda sempre que se multiplica um digito que está mais para a esquerda, na verdade se escreve o resultado da multiplicação exatamente na mesma coluna que se está multiplicando.

No processo binário é muito parecido, porém se desloca toda a linha superior ao observar cada bit da linha inferior, e se esse bit da linha inferior for um (1) soma-se a linha superior ao resultado, caso seja zero, continua-se movendo a linha superior para a esquerda até acabarem os bits da linha inferior.

Lembre-se de passar os zeros do 300 e do 20 para o 76, aqui abaixo é o mesmo, conforme vamos tirando bits do multiplicador (vemelho), estamos enfiando zeros na Linha Superior (azul).

Veja:

[raw]

Linha Superior Multiplicador
- – - – 1 1 0 1 0 1 0 1
Olhe o ultimo bit à direita do Multiplicador acima (em vermelho), se for um (1), soma-se a Linha Superior ao  Resultado. Desloca-se a linha superior uma posição para à esquerda, enfia-se um zero à direita, desloca-se o Multiplicador (acima) um bit à direita, ou seja, elimina-se o bit mais à direita do Multiplicador.  Nesse caso, o ultimo bit à direita do Multiplicador acima é “1″, então os bits da Linha Superior “1101″ são adicionados ao Resultado.
- – - 1 1 0 1 0 0 1 0
Olhe o ultimo bit à direita do Multiplicador acima (em vermelho), como é zero (0), os bits da Linha Superior “11010″ não será adicionado ao Resultado.  Porém a Linha Superior será deslocada um bit à esquerda, e o ultimo bit to Multiplicador (acima em vermelho) será eliminado.
- – 1 1 0 1 0 0 0 1
Olhe o ultimo bit à direita do Multiplicador acima (em vermelho), como é um (1), os bits da Linha Superior “110100″ (com os dois ultimos bits em azul) serão adicionados ao Resultado.  Então a Linha Superior será deslocada um bit à esquerda, e o ultimo bit to Multiplicador (acima em vermelho) será eliminado.
- 1 1 0 1 0 0 0 0
Olhe o ultimo bit à direita do Multiplicador acima (em vermelho), como é zero (0), nada será adicionado ao Resultado, e como ele é o último bit do Multiplicador, a operação está encerrada e o Resultado é o valor da multiplicação entre a Linha Superior e o Multiplicador.
- – - – 1 1 0 1                                                                                                                                                                                                                                      À esquerda as somas ao Resultado das quatro operações acima.  Os bits (1) do Resultado são 1 e 64, que somados formam 65 em decimal, portanto está correta a multiplicação.
- – - 0 0 0 0 0
- – 1 1 0 1 0 0
- 0 0 0 0 0 0 0
- – - – - – - – -
- 0 1 0 0 0 0 1

[/raw]

Percebeu como é simples e fácil?
Basta ir olhando para os bits da linha inferior.  Para cada bit que você olha mais para a esquerda, enfia um zero ao final da linha superior.  Se o bit que olhou na linha inferior é 1, some a linha superior no resultado.  É só isso.

Ao fazer isso em Assembly, usa-se deslocar para a direita a linha de baixo, se ocorreu “carry bit”, ou seja, o bit mais à direita da linha de baixo era “1″, e o carry bit é “1″, então soma-se a linha superior ao registrador do resultado.  Se o bit mais à direita da linha de baixo era “0″ e agora o carry bit é zero então não se soma nada ao resultado.  Então shifta-se toda a linha superior um bit à esquerda, independente dela ter sido somada ao resultado ou não.   Repete-se essa sequência até a linha de baixo só ter zeros.

Pronto, o registrador de resultados já terá o valor da multiplicação.  Veja que essa técnica funciona para qualquer quantiadade de bits ou bytes, basta ter espaço para shiftar para a esquerda a linha superior e ter espaço no registrador de resultados para ir fazendo as somas.

Soma e Subtração em Binário

Atendendo a um amigo que pediu para explicar como multiplicar e dividir em assembly.

Antes de mais nada é importante entender muito bem o sistema binário e hexadecimal, e vou explicar primeiro a somar e subtrair em binário, no próximo post veremos multiplicação e no outro divisão.

Pense nos 5 dedos da sua mão direita, com eles você pode contar de 1 a 5, é o que aprendeu na escola. Isso significa que pode contar 5 coisas, digamos, bananas.  Na verdade, consegue contar 6, se imaginar que com todos os dedos fechados pode significar a sexta ou a primeira banana.   Mas isso é só para dar partida na sua cabeça, tudo pode ser diferente.

Bem, então pense que eu posso fazer você contar 32 bananas só com os 5 dedos da mão direita. Opa, como é que é? Pois é, essa é a forma de contagem binária.

Vamos aproveitar para dar nomes e valores aos dedos da mão direita.

Mão direita – Nome do Dedo Valor do Dedo
Mínimo 1
Anelar 2
Médio 4
Indicador16 8
Polegar 16

Hmmm, veja que a partir do mínimo que vale “1″, os valores dos outros dedos são sempre o dobro do anterior.  Significa que ao levantar o polegar e fazer o “sinal de positivo”, está mostrando o numero 16.

Ao fazer o “V” de vitória com o indicador e médio, está mostrando 12, que é a soma deles (8 e 4).

Ao fechar o polegar e levantar os outros 4 dedos (como quem mostra o numero 4), em binário estará mostrando 15, que é a soma de 1+2+4+8.

Interessante, não?

Veja, o numero decimal 7 é representado pelos tres dedos, mínimo, anelar e médio. Para subtrair 2, basta fechar o dedo anelar (que vale 2) e ver o que restou levantado, o médio (4) e o mínimo (1), cuja soma é 5.

Bacana, não é? Pois é.  Isso é binário e pode-se fazer somas, subtrações e até multiplicações e divisões.

Quer ver? Faça o “V” de vitória, indicador e médio, que é 12 (8+4).
Dividir por 2 ?  basta mover esse “V” um dedo para a direita, vai levantar o médio e o anelar.  Quanto valem? 2 + 4 = 6… ora, 12 / 2 = 6.

Volte novamente a fazer o “V” da vitória, que é 12.  Agora vamos dividir por 4, ora, dividir por 4 requer deslocar o “V” duas posições para a direita, vai então fazer o “V” com o anelar e o mínimo.  Vale quanto? 1+2 =3

Ahaa… 12 / 4 = 3

Simples?  Pois é, então multiplicação é o contrário, ao multiplicar por 2 desloca o V para a esquerda um dedo, multiplicar por 4, desloca o V dois dedos, e por ai vai.

Hmmm, mas só dá para contar até 31 com uma mão ?  Sim, se incluir o zero (todos os dedos baixos) conta-se 32 movimentos.

Mas se usar a mão esquerda junto com a direita, sendo o polegar da esquerda então valendo o dobro do polegar da direita, 32, então o dedo mínimo da mão esquerda vai valer o máximo de todos os dedos, irá valer 512, vejamos:

DICA: Você pode até fazer anéis de papel e vesti-los nos dedos, cada um com o valor acima, para entender direitinho essa coisa de “binário”.

Uau, então se levantar só os dois polegares, estarei mostrando 32 + 16 = 48  em binário?  Sim, com só dois dedos, mostrará 48.

Note que o mínimo direito só vale “1″, mas é ele quem determina se a contagem binária dos dedos será “par” ou “impar”… até ele que vale menos é super importante.  Por outro lado, o mínimo esquerdo é o que tem mais valor, 512, por estar mais à esquerda de todos os outros dedos.

E se levantar os cinco dedos direitos, como dizendo “olá” para o amigo, está mostrando 16+8+4+2+1 = 31… e se levantar todos os dedos só da mão esquerda, estará mostrando 512 + 256+ 128 + 64 + 32 = 992, e se levantar todos os dedos das duas mãos, estará mostrando 1023.

Portanto, “Olá!!!” com a mão direita… 31, com a mão esquerda… 992

Okay, você está curioso.  E se a pessoa não tiver o mínimo da mão esquerda? bem, nesse caso ele só contará até 511, e só contará até a metade dos 1023 e o apelido “meia conta” poderá grudar nele.

Se estiver com todos os dedos levantados e deslocar isso um dedo para a direita, o que ocorre?
Obviamente que o dedo mínimo esquerdo (512) vai baixar, porque não existe nenhum dedo à esquerda dele para ser copiado para ele, mas todos os outros dedos movem para a direita, e todos continuarão levantados.  O que acontece com o mínimo direito (1) ao ser deslocado para a direita? ele some, porque não existe nenhum dedo à direita dele para copia-lo.   Então todos os dedos permanecem levantados, exceto o mínimo esquerdo (512), e agora temos 9 dedos levantados, que somando valem 511, exatamente o mesmo de todos os 10 dedos (1023) menos o 512 do mínimo da esquerda que baixou.

Opa, 511 é um a menos do valor 512 do mínimo esquerdo.  Certo, pois se somar um nessa conta dos nove dedos levantados, não existe lugar para esse “um” entrar e ele corre e levanta o mínimo esquerdo e derruba todos os 9 dedos que estavam lentados e a soma passa a ser 511+1 = 512.

Vamos esquecer os dedos e ver da forma binária, mas vamos só usar 4 bits (bits=dedos), e vamos dar nomes à esses bits, 8, 4, 2, 1.

 Bit  8  4  2  1
      — – — –
      0  1  0  0  < Valor decimal 4, só o bit 4 está levantado
      1  0  1  1  < Valor decimal 11, 8 + 2 + 1
      1  0  0  0  < Valor decimal 0, nenhum bit levantado
      1  1  1  1  < valor decimal 15, todos os bits levantados

Que tal então darmos nomes diferentes para cada uma dessas combinações?  Veja, são 16 combinações e uma boa parte delas é conhecida, de zero a nove, mas ainda existem a 11, 12, 13, 14 e 15.   Para facilitar vamos nomear essas combinações acima de nove em A, B, C, D, E, F.   Então vai ficar assim:

HEXADECIMAL
8 4 2 1 < bits
– - – -
0 0 0 0 = 0
0 0 0 1 = 1
0 0 1 0 = 2
0 0 1 1 = 3
0 1 0 0 = 4
0 1 0 1 = 5
0 1 1 0 = 6
0 1 1 1 = 7
1 0 0 0 = 8
1 0 0 1 = 9
1 0 1 0 = A
1 0 1 1 = B
1 1 0 0 = C
1 1 0 1 = D
1 1 1 0 = E
1 1 1 1 = F

Muito bem, agora temos o nome desses numeros de zero a 15, que é de zero a F.

Parabéns, acabou de parender HEXADECIMAL, uma forma de contar de zero a 15 (F) com quatro bits.
Só para fixar, “A” + 1 é o que? é “B”, e 7 + 3 o que é? não é 10, é “A”, lembre-se, estamos falando de hexadecimal, e não mais decimal, okay?

A forma usual de representar um valor qualquer em hexadecimal é incluindo “0x“, ou “$” atrás do numero:

“5″ em hexadecimal pode ser representado assim:
0×5 ou 0×05 ou $5 ou $05

“5″ em binário é “0101″ e deve ser representado com “0b” atrás dos bits:
0b0101

“5″ em decimal pode ser representado basicamente como “5″, mas para evitar confusão usaremos “0d” atrás do numero:
0d05

Ah sim, “atrás” do número é do lado esquerdo, também chamado de “prefixo”, pois o que vem a frente é à direita do número, chamado de “sufixo”.

Okay, eu também não concordo com isso, mas já fui severamente acusado de usar isso errado.

Observe a combinação de bits, olhe o “E” e olhe o “7″.  Se deslocar o 7 um bit para a esquerda, ele vira “E”, e se deslocar o “C” uma vez para a direita? vira 6.  E se deslocar mais uma vez para a direita? vira 3.  E se deslocar mais uma vez para a direita? vira 1.  Ué? 3 dividido por 2 resulta em 1?  Pois é, não tem como representar meio bit, pois o certo seria 1,5 mas não dá.  Binário só conta inteiros, a menos que se defina isso diferente, verá isso mais a frente.

 Parabéns, já descobriu como dividir e multiplicar em binário…

 Opa, mas e se eu quiser multiplicar por 3 e não só por 2, 4, 8, etc?

O segredo está em somar resultados parciais.  Você faz o mesmo em decimal no papel e lápis. Mas isso veremos no próximo post desse blog, Multiplicando e Dividindo em Binário.

SOMA EM BINÁRIO
8 4 2 1  <–  Bits0 1 1 0  = 6
0 0 0 1  = 1 +
——-

Okay, mas como somamos Bits?  É fácil, basta seguir uma regrinha simples que só usa “0″ e “1″.

0  +  0  =  0
0  +  1  =  1
1  +  0  =  1
1  +  1  =  10

Oooopa, 1+1 = 10? não seria 2 ?  Bem, seria “2” se fosse em decimal, mas aqui estamos somando em binário e binário só tem zeros e uns.  Lembre-se agora cada bit só pode ser representado por “0″ ou “1″. Lembre-se dos dedos levantados ou baixados.  

Para facilitar pense assim:

Binário     Decimal

00    =    0
01    =    1
10    =    2
11    =    3

Então vamos fazer a tal soma ai acima:

8 4 2 1  <–  Bits
——- 
0 1 1 0  = 6 
0 0 0 1  = 1 + 
- – - - 
      1 = 0 + 1 
    1   = 1 + 0
  1     = 1 + 0 
0       = 0 + 0 
- – - – baixando e somando tudo 
0 1 1 1 = 7

Esse foi fácil, vamos complicar?

8 4 2 1  <–  Bits 
——- 
0 1 1 0  = 6    (Bits da Linha de Cima)
0 0 1 0  = 2 +  (Bits da Linha de Baixo)
- – - –  
      0 = 0 + 0  (Bit1C + Bit1B)
  1 0   = 1 + 1  (Bit2C + Bit2B) ocorreu “vai um”
  1     = 1 + 0  (Bit4C + Bit4B)
0       = 0 + 0  (Bit8C + Bit8B)
- – - – baixando e somando tudo 
1 0 0 0 = 8

Ooopa, que raios é Bit4C ???

Vamos fazer uma convenção aqui.

A soma aí acima tem 4 bits, 8, 4, 2 e 1, vamos chamar cada coluna dessa de Bit8 Bit4 Bit2 e Bit1. Como estamos lidando com duas linhas, vamos chama-las de linha de cima e linha de baixo, então teremos Bit8C, Bit4C, Bit2C e Bit1C (os quatro bits de cima), e BIt8B, Bit4B, Bit2B, Bit1B (os quatro bits de baixo), e também teremos os quatro bits do resultado, Bit8R, Bit4R, Bit2R e Bit1R.
Se fossemos falar em voz alta a soma acima, seria assim, começando pela direita para a esquerda:

(Bit1C + Bit1B) Zero mais Zero igual a zero, (Bit2C + Bit2B) um mais um é igual a zero e “vai um” à esquerda, esse “vai um” é somado com os Bit4C + Bit4B, então, UM (que foi), mais um (Bit4C), mais zero (Bit4B), igual a zero e “vai um” à esquerda, que quando somado com os zeros (Bit8C + Bit8B); o UM (que foi), mais zero, mais zero, é UM, que aparece embaixo como Bit8R.

Soma em binário é bem simples, basta pegar a idéia.

SUBTRAÇÃO

Subtração é exatamente o inverso, vejamos:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 0 1  = 1 –
- – - -

Vamos olhar como se olha em subtrair em decimal.  O Bit1B deverá ser subtraido do Bit1C, mas não dá para subtrair um de zero, então empresta-se o próximo bit à esquerda na linha de cima (Bit2C), então estaríamos subtraindo o valor “1″ (Bit1B) dos dois bits valor “1″ e “0″ (Bit2C Bit1C) da linha de cima, veja:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 0 1  = 1 –
- – - -

Agora dá, pois “1 0” em binário, (Bit2C e Bit1C), significa “2″ em decimal, e o valor “1″ (Bit1B) pode ser subtraido.

Então binário “10 – 1″  é o que?
Veja, “10″ em binário é “2″ em decimal, certo?  Então, em decimal 2-1 = 1, okay?
Então, em binário “10 – 1″ = “1″
Ficou claro? para ir em frente isso TEM que ficar claro.

Então o valor binário “1”  (Bit1B) subtraindo do valor binário “10” (Bit2C Bit1C) resulta em valor binário “1″ (Bit1R), mas emprestou um da esquerda, lembre-se disso, exatamente como se faz em decimal, e fica assim:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 0 1  = 1 –
- – - –
      1

Agora, o um emprestado é somado na nossa mente na posição certa, (Bit2B), ficando assim:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 1 1  = 1 –
- – - –  
    0 1

Então, agora os dois Bit2C e Bit2B, valor binário “1“,  se anulam, e sobra zero em Bit2R.

O resto vai fácil, os dois bits4, 1 – 0 = 1 e zero – zero (os dois bits 8) = 0, o que resulta em:

8 4 2 1  <–  Bits
——-
0 1 1 0  = 6
0 0 0 1  = 1 –
- – - –  
0 1 0 1 = 5

Opa, 6 – 1 = 5.  Simples, não?

Bem, creio que deu para entender, no próximo post veremos multiplicação e divisão.