Saltar para o conteúdo

Representação de números com sinal

Origem: Wikipédia, a enciclopédia livre.

Em computação, representações de número com sinal são modos de representar números com sinal, i.e. números positivos e negativos, em sistemas de números binários.

Em matemática, os números negativos em qualquer base são representados por prefixando-os com um sinal de −. No entanto, em um hardware computacional, os números são representados em binário apenas, sem símbolos extras, requerendo um método de codificação para números negativos. Quatro métodos existem para estender o sistema binário para representar números com sinal: sinal-e-magnitude, complemento para um, complemento de dois, e excesso-N.

Método sinal-e-magnitude

[editar | editar código-fonte]
Sinal-e-magnitude de 8 bits
Binário com Sinal sem Sinal
00000000 +0 0
00000001 1 1
... ... ...
01111111 127 127
10000000 −0 128
10000001 −1 129
... ... ...
11111111 −127 255

A representação de sinal-e-magnitude ou sinal-magnitude é a mais familiar a nós que utilizamos o sistema numérico de base 10, usando um sinal positivo ou negativo à esquerda do número para indicar se este é positivo ou negativo.[1] Pode-se primeiramente abordar o problema de representar um sinal de número através da atribuição de um bit de sinal para representar o sinal: define-se esse bit (frequêntemente o bit mais significativo) para 0 para representar um número positivo, e define-se como um para representar um número negativo. Os bits restantes do número representam a magnitude (ou o valor absoluto). Assim, em um byte com 8 bits, são utilizados 7 bits para representar o valor e um bit para representar o sinal. Neste caso, o valor pode variar de 0000000 (0) a 1111111 (127). Assim, pode-se representar números de −12710 a +12710 (-(2N−1−1) a +(2N−1−1)),[2] onde n é a quantidade de bits do número), uma vez que você adicione o bit de sinal (o oitavo bit). Uma conseqüência desta representação é que existem duas maneiras de representar o zero, 00000000 (0) e 10000000 (-0).[3]

Esta abordagem é directamente comparável com a maneira comum de se mostrar um sinal (colocando um "+" ou "-" junto à magnitude do número). Alguns dos primeiros computadores binários (por exemplo, o IBM 7090) usaram esta representação, talvez por causa de sua relação natural com o uso comum.[carece de fontes?] Sinal de magnitude é a forma mais comum de representar os significandos em valores de ponto flutuante.

Complemento para um

[editar | editar código-fonte]
Complemento para um com 8 bits
Binário Interpretação de complemento para um Interpretação sem sinal
00000000 +0 0
00000001 1 1
... ... ...
01111101 125 125
01111110 126 126
01111111 127 127
10000000 −127 128
10000001 −126 129
10000010 −125 130
... ... ...
11111110 −1 254
11111111 −0 255

Como alternativa, um sistema conhecido como complemento para um ou complemento de um pode ser usado para representar números negativos. A forma de representar números negativos em "complemento para um" é aplicar a operação bitwise NOT para os números negativos (com -), ou seja, o complemento da sua contraparte positiva. Como na representação sinal de magnitude, o "complemento para um" tem duas representações para o 0: 00000000 (+0) e 11111111 (-0). Na prática, este zero negativo, quando detectado é transformado em zero normal.[4]:p.17,18

Como exemplo, a forma em complemento para um de 00101011 (43) torna-se 11010100 (-43). O intervalo de números com sinal usando complemento para um é representado por: −(2N−1−1) para (2N−1−1) e +/-0. Um byte de oito bits convencional é −12710 para +12710 com zero sendo ou 00000000 (+0) ou 11111111 (-0).

Nesse caso citado, para transformar o número binário em decimal, segue-se o padrão normal, porém sem contar o primeiro número. Vamos usar o número 00101011 como exemplo, o primeiro 0 da esquerda é apenas para indicar o sinal e não faz parte da conta, portanto (0 + 2^5 + 0 + 2^3 + 0 + 2^1 + 2^0) = (0 + 32 + 0 + 8 + 0 + 2 + 1) = 43.

Para adicionar dois números representados neste sistema, se faz uma adição binária convencional, mas é então necessário adicionar qualquer "vai-um" resultante de volta para a soma resultante. Para ver por que isso é necessário, considere o seguinte exemplo que mostra o caso da adição de −1 (11111110) a +2 (00000010).[3]:p.19

         binário    decimal
        11111110     -1
     +  00000010     +2
    ............    ...
      1 00000000      0   <-- não é a resposta correta
               1     +1   <-- adiciono "vai-um"
    ............    ...
        00000001      1   <-- resposta correta

No exemplo anterior, a adição binária somente dá 00000000, o que é um resultado incorreto. Somente quando o "vai-um" é adicionado de volta o resultado correto (00000001) aparece.

Este sistema de representação numérica era comum em computadores mais antigos; o PDP-1, CDC 160A e a série UNIVAC 1100/2200, entre muitos outros, utilizavam aritmética de "complemento para um".[carece de fontes?]

Uma observação sobre a terminologia: O sistema é conhecido como "complemento para um", porque a negação de um valor positivo x(representado como a operação bitwise NOT de x) pode também ser formado pela subtração de x da representação em "complemento para um" do número zero que é uma longa seqüência de uns (-0). A aritmética de "Complemento de dois", por outro lado, constitui a negação de x subtraindo x a partir de uma única grande potência de dois que é congruente a 0.[5] Por isso, a representação de "complemento para um" e a representação de "complemento para dois" irão diferir de um.

Os protocolos Internet IPv4, ICMP, UDP e TCP usam todos o mesmo algoritmo checksum de 16 bits de complemento para um. Embora a maioria dos computadores careça de um hardware para método de complementos, a complexidade extra é aceita porque "é igualmente sensível a erros em todas as posições dos bits".[6] No UDP, a representação de zero com todos os bits setados para 0s indica que o recurso de verificação opcional foi omitido. A outra representação, FFFF, indica um valor de checksum 0.[7] (Checksums são obrigatórios em IPv4, ICMP e TCP; eles foram omitidos do IPv6).

Note que a representação de complemento para um de um número negativo pode ser obtida de uma representação sinal-e-magnitude simplesmente fazendo-se uma operação de complemento bitwise da magnitude.[necessário esclarecer]

Complemento para dois

[editar | editar código-fonte]
Complemento para dois de 8 bits
Binário Interpretação de complemento para dois Interpretação sem sinal
00000000 0 0
00000001 1 1
... ... ...
01111110 126 126
01111111 127 127
10000000 −128 128
10000001 −127 129
10000010 −126 130
... ... ...
11111110 −2 254
11111111 −1 255
Ver artigo principal: Complemento para dois

Os problemas de múltiplas representações de 0 e a necessidade de tratamento com "vai-um" são contornadas por um sistema chamado complemento para dois.[3]:p.21 Neste modelo, os números negativos são representados pelo padrão de bits que é maior em uma unidade (no sentido sem-sinal) que o "complemento para um" do valor positivo.

Em complemento para dois, há apenas um zero (00000000). Se nega um número (negativo ou positivo) invertendo-se todos os bits e, em seguida, adicionando 1 ao resultado. A adição de um par números em complemento para dois é o mesmo a adição de um par de números sem-sinal . Por exemplo, um complemento para dois da adição de 127 e -128 dá o mesmo padrão de bits binário de uma adição sem sinal de 127 com 128, como pode ser visto na tabela ao lado.[3]:p.21

Um método mais fácil de obter a negação de um número em complemento de dois é o que se segue:

Exemplo 1 Exemplo 2
1. A partir da direita, encontre o primeiro '1' 0101001 0101100
2. Inverte todos os bits à esquerda deste um 1010111 1010100
Ver artigo principal: Offset binário
Excesso-127 em 8 bits
Valor binário Interpretação de Excesso-127 Interpretação sem-sinal
00000000 -127 0
00000001 -126 1
... ... ...
01111111 0 127
10000000 1 128
... ... ...
11111111 +128 255

A representação de Excesso-N usa um número pré-especificado N como um valor de polarização. Um valor é representado pelo número sem sinal que é N unidades maior do que o valor pretendido. Assim, 0 é representado por N, e -N é representado pelo padrão de bits zeros (tudo zerado).

Esta é uma representação que é agora utilizada principalmente em números de ponto flutuante. O padrão IEEE de ponto flutuante, define o campo de expoente de um número de 32 bits de precisão simples como um campo de 8 bits na representação de Excesso-127. O expoente de um número de 64 bits de precisão dupla é um de campo de 11 bits com representação de Excesso-1023.

Em sistemas convencionais de número binário, a base, ou raiz, é de 2; assim, o bit mais à direita representa 20, o próximo bit representa 21, o próximo bit 2², e assim por diante. No entanto, um sistema numérico binário com base -2 também é possível. O bit mais à direita representa (−2)0=+1, o próximo bit representa (−2)1=−2, o próximo bit (−2)²=+4, e assim por diante, com o sinal alternado. Os números que podem ser representados com quatro bits são mostrados na tabela de comparação abaixo.

O intervalo de números que pode ser representado é assimétrico. Se a palavra tem um número par de bits, a magnitude do maior número negativo que pode ser representado é duas vezes maior que o maior número positivo que pode ser representado, e vice-versa, se a palavra tem um número ímpar de bits.

Tabela de comparação

[editar | editar código-fonte]

A tabela abaixo mostra os números inteiros positivos e negativos que podem ser representados utilizando 4 bits.

representações inteiras de 4 bits
Decimal Sem sinal Sinal-e-magnitude Complemento para um Complemento de dois Excesso-7 Base −2
+16
+15 1111
+14 1110
+13 1101
+12 1100
+11 1011
+10 1010
+9 1001
+8 1000 1111
+7 0111 0111 0111 0111 1110
+6 0110 0110 0110 0110 1101
+5 0101 0101 0101 0101 1100 0101
+4 0100 0100 0100 0100 1011 0100
+3 0011 0011 0011 0011 1010 0111
+2 0010 0010 0010 0010 1001 0110
+1 0001 0001 0001 0001 1000 0001
+0 0000 0000
0 0000 0000 0111 0000
−0 1000 1111
−1 1001 1110 1111 0110 0011
−2 1010 1101 1110 0101 0010
−3 1011 1100 1101 0100 1101
−4 1100 1011 1100 0011 1100
−5 1101 1010 1011 0010 1111
−6 1110 1001 1010 0001 1110
−7 1111 1000 1001 0000 1001
−8 1000 1000
−9 1011
−10 1010
−11

Referências

  1. MURDOCCA, Miles J.; HEURING, Vincent P. (2001). Introdução à Arquitetura de Computadores. Rio de Janeiro: Campus, Elsevier. pp. 28–32. ISBN 85-352-0684-1 
  2. Boeres, Cristina (2016). Representações de Números Inteiros: Sinal e Magnitude e Representação em Excesso de k Cristina Boeres Instituto de Computação (UFF) Fundamentos de Arquiteturas de Computadores (PDF). Fundamentos de Arquiteturas de Computadores. Niterói, RJ: Instituto de Computação (UFF). p. 14 
  3. a b c d Anido, Ricardo (fevereiro de 2011). «Introdução à Organização de Computadores e Linguagens de Montagem» (PDF). Universidade Estadual de Campinas. Consultado em 4 de março de 2012 [ligação inativa]
  4. BIANCHI, Paulo; BEZERRA, Milton (1983). Microcomputadores. Arquitetura - Projeto - Programação. [S.l.]: LTC. 16 páginas. ISBN 85-216-0321-5 
  5. Donald Knuth:The Art of Computer Programming, Volume 2: Algoritmos Seminumerical, capítulo 4.1
  6. Braden, R. (setembro de 1988). «Computing the Internet Checksum (RFC 1071)» (em inglês). The Internet Engineering Task Force. Consultado em 11 de junho de 2009 
  7. Postel, J. (agosto de 1980). «User Datagram Protocol (RFC 768)». The Internet Engineering Task Force. Consultado em 11 de junho de 2009 

Andrew S.Tanenbaum, Organização Estrutura de Computadores, pág 399, Anexo 3