• Aula 5 - Aritmética Binária

Aritmética Binária

  • Conteúdo: Complemento de um/ Complemento de dois/ Ponto fixo/ Soma binária/

(mesmo vídeo da aula de Teoria de Dados)

Podemos utilizar números binários para codificar qualquer tipo de dado, como vimos na teoria de dados digitais. Mas ainda não sabemos como utilizar números binários para representar: números inteiros que possam ser negativos e números reais fracionados (exemplo: -15; 1,032; -0,0001; 10001231231).

Essa teoria irá tratar desses temas e também da parte referente a operações com números binários (soma e subtração).

Soma binária

A soma binária é realizada de maneira similar a soma de decimais, só que precisamos reforçar que 1+1 em binário (esse + é de soma não de OR), resulta em 10, o 1 do estouro e que passa para a próxima casa é chamado de carry. Esse carry é similar ao vai um em uma soma decimal, por exemplo: quando somamos em decimal 9 + 3 o resultado é 12 (10 + 2).

Exemplos a seguir consideram

  • Palavras binárias com 8 bits
  • Números inteiros positivos

Tip

  • 01 + 01 = 10
  • 01 + 01 + 01 = 11
  • 10 + 10= 100
  • 0xAA + 0x55 = 0xFF
                          : Carry
     1 0 1 0 1 0 1 0      : A 
     0 1 0 1 0 1 0 1 +    : B
     ---------------  
     1 1 1 1 1 1 1 1      : Resultado (A+B)
  • 0xAA + 0x55 = 0xFF
                          : Carry
     1 0 1 0 1 0 1 0      : A 
     0 1 0 1 0 1 0 1 +    : B
     ---------------  
     1 1 1 1 1 1 1 1      : Resultado (A+B)
  • 0x2B + 0x57 = 0xFF
     1 1 1 1 1 1 1        : Carry
     0 0 1 0 1 0 1 1      : A 
     0 1 0 1 0 1 1 1 +    : B
     ---------------  
     1 0 0 0 0 0 1 0      : Resultado (A+B)

Precisamos entender que cada bit deve ser armazenado em hardware! Um sistema com 8 bits não consegue armazenar 9 bits, e se houver um estouro no último bit essa informação será perdida.

Note

Os bits são armazenados na memória, as memórias armazenam vetores de bits. Computadores reais não possuem memória infinita e nem largura de bits infinita.

  • 0x80 + 0x80 = 0x100, mas resulta em 0x00 por conta do somador ser 8 bits:
carry é perdido
   x
    \
     1 0 0 0 0 0 0 0 
     1 0 0 0 0 0 0 0 +
     ---------------
     0 0 0 0 0 0 0 0
  • 0x03 + 0x81 = 0x84
               1 1        : carry (vai um)
                  \       
     0 0 0 0 0 0 1 1 
     1 0 0 0 0 0 0 1 +
     ---------------
     1 0 0 0 0 1 0 0    

Complemento de um

Warning

Forma errada/ não usual de armazenar números sinalizados (+, -)

Exemplos a seguir consideram

  • Palavras binárias com 8 bits
  • Números inteiros positivos

No complemento de um, utilizamos a casa/bit mais significativa de um vetor de bits para representar se o número é positivo (0) ou negativo (1). Exemplo (utilizando 8 bits):

  • Valor +1 em binário, com complemento de 1
    00000001
    ^
    | indica que o valor é positivo
  • Valor -1 em binário, com complemento de 1
    10000001 
    ^
    | indica que o valor é negativo

O problema do complemento de 1 é que:

  • Possuímos duas representações para o valor 0: 00000000 e 10000000
  • Operações de soma não funcionam corretamente entre os dois números codificados em complemento de um.

  • Exemplo: 1 - 1 = -2 e não 0

                 1        : carry (vai um)
                  \       
     0 0 0 0 0 0 0 1      : +1
     1 0 0 0 0 0 0 1 +    : -1
     ---------------
     1 0 0 0 0 0 1 0      : -2 e não 0 

Tabela com 3 bits

Decimal Binário em complemento de 1
3 011
2 010
1 001
0 000 / 100
-1 101
-2 110
-3 111

Complemento de 2

O complemento de dois é uma outra maneira de representar números sinalizados com bits, essa técnica possui alguams vantagens:

  • Uma única representação para o valor 0: 0000
  • A operação de soma/ subtração funciona corretamente!
  • O bit mais significativo indica se a palavra é positiva (0) ou negativa (1).

Para obter um número positivo ↔ negativo nessa notação é necessário seguir os seguintes passos:

  1. Escreva o valor em binário (positivo)
  2. Inverter todos os bits (not bit a bit) da palavra original
  3. Somar o valor 1 a palavra invertida.

  4. Exemplo: -3 = 11111101

     0 0 0 0 0 0 1 1      : 3
    -----------------------
     1 1 1 1 1 1 0 0      : not bit a bit da palavra original
     0 0 0 0     + 1      : Soma um a palavra invertida
    -----------------------
     1 1 1 1 1 1 0 1  <-- -3 em complemento de 2       
  • Exemplo: -5 = 111111011
    0 0 0 0 0 1 0 1      : 5
    -----------------------
    1 1 1 1 1 0 1 0      : not bit a bit da palavra original
    0 0 0 0 0 0 0 1 +    : Soma um a palavra invertida
    -----------------------
    1 1 1 1 1 0 1 1  <-- -5 em complemento de 2
  • Exemplo (com 4 bits para simplificar): -9 (não funciona porque não cabe)
(exemplo com 4 bits!)

     1 0 0 1      : 9
     0 1 1 0      : not bit a bit da palavra original
         + 1      : Soma um a palavra invertida
     0 1 1 1    <-- 7 !! (não funcionou)
     ^
     | não funcionou =(

O exemplo anterior não funciona pois faltam bits para representar o valor -9, para isso seria necessário 5 bits e não 4 como no exemplo.

Tabela com 3 bits

Decimal Binário em complemento de dois
3 011
2 010
1 001
0 000
-1 111
-2 110
-3 101
-4 100

Multiplicação/ Divisão por múltiplo de 2

Assumindo

  • Um número positivo

Em binário, para multiplicar uma palavra (positiva) por 2 basta rotacionar todos os bits uma casa para esquerda. Para dividir por 2 basta rotacionar todos os bits uma vez para direita (sempre colocando 0 no bit que entra e desaparecendo com o bit que sai).

Exemplos a seguir:

  • 2 x 1 (00000001) = 2 00000010
      <-- 1x 
    00000001 => 00000010
  • 2 x 4 (00000100) = 8 00001000
      <-- 1x 
    00000100 => 00001000
  • 9 (00001001) / 2 = 4 00000100
1x --> 
    00001001 => 00000100

Note

A divisão de 9/2 retorna um número inteiro. Isso se dá devido a técnica só funcionar com números inteiros.

Essa técnica de rotacionar vale para múltiplos de 2, se deseja multiplicar/dividir por M, onde M é um múltiplo de 2 (M=Nx2), é necessário rotacionar o vetor de bits N vezes:

  • exemplo: 4 x 1 (00000001) = 00000100
      <-- 2x 
    00000001 => 00000100

Multiplicação Binária (unsigned)

A multiplicação em binário segue o mesmo princípio que a multiplicação em decimal: vamos multiplicar cada bit do multiplicando com o multiplicador e somar os resultados.

Vamos entender com um exemplo:

Exemplo

Vamos multiplicar 101 (5 em decimal) por 11 (3 em decimal).

   101  (multiplicando)
 x  11  (multiplicador)
 _____
   101  (101 multiplicado por 1 - a posição mais à direita do multiplicador)
  101   (101 multiplicado por 1 - a segunda posição do multiplicador, deslocado para a esquerda)
 ______
  1111  (resultado)

Então, em binário, 101 multiplicado por 11 é igual a 1111.

Passos

  1. Comece pela posição mais à direita (bit menos significativo) do multiplicador.
  2. Multiplique o multiplicando pelo bit do multiplicador.
  3. Anote o resultado.
  4. Desloque o multiplicando uma posição para a esquerda.
  5. Vá para o próximo bit à esquerda do multiplicador e repita os passos 2 a 4.
  6. Some todos os resultados intermediários.

Observações:

  • Multiplicar por 0 sempre resulta em 0.
  • Multiplicar por 1 é o mesmo que o próprio número.

Ao realizar multiplicações maiores, a quantidade de etapas intermediárias aumentará, mas o princípio básico é o mesmo. E, assim como na multiplicação decimal, a prática leva à perfeição. Uma vez que você entende o processo básico, multiplicar números binários torna-se tão fácil quanto multiplicar números decimais.

Exercise

Dado os números binários 1001 (9 em decimal) e 10111 (23 em decimal), realize a multiplicação binária e forneça o resultado.

Answer

     1001   (multiplicando)
  x 10111   (multiplicador)
 ________
     1001
    1001    
+  1001     
  0000      
 1001       
 _________
 11001111   (resultado)

Multiplicação Binária (com sinal)

Informacões do site do IF de Santa Catarina

A técnica é muito similar, só que temos que considerar a extensão dos bits quando ele é negativo:

Warning

No caso dos dois números negativos a regra é um pouco difente e não iremos tratar no curso.

Ponto fixo

Ponto fixo é uma das técnicas de representação de números fracionados em binário, nessa notação fixasse quantos bits serão utilizados para a parte inteira e quantos serão utilizados para a fração. É aplicado o mesmo conceito dos números decimais, as casas a direita do ponto possuem peso na ordem 2^-n.

Vamos pegar como exemplo o valor 26.5, e assumindo que estamos trabalhando com uma palavra de 8 bits onde o ponto está localizado no bit 3: XXXXX.YYY.

Nesse caso, cada casa binária possui o peso a seguir:

2^5 2^4 2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3
32 16 8 4 2 1 0.5 0.25 0.125

Para construirmos o valor 26.5 basta selecionarmos os bits que somados dão esse valor:

011010100 : 0*32 + 1*16 + 1*8 + 0*4 + 1*2 + 0*1 + 1*0.5 + 0*0.025 + 0*0.125 = 26.5

A questão dessa notação é que uma vez escolhido onde o ponto vai estar localizado (projeto de hardware) não da para mudar depois, se o número a ser armazenado é apenas fração, perdemos muitos bits sem uso com a parte inteira, o que faz possuirmos menor resolução.

A solução para isso é a notação de ponto flutuante - IEEE 754 vocês vão ver isso na disciplina de Sistemas Hardware Software do 5s).

Ponto flutuante

Ponto flutuante é uma outra notação na qual é possível representar números racionais digitalmente (binário), nessa técnica a vírgula não é fixa, e a notação pode se adequar para armazenar números muito trandes ou muito pequenos. No entanto, existe um custo computacional mais elevado envolvido nisso.

Processadores modernos possuem um hardware (ULA) dedicada a realizar operações em ponto flutuante, normalmente usando o padrão IEEE 754.