Por que o zero é tratado como sinal positivo?

0

Em int assinado ou em dígito binário

Zero is treated as positive sign

e

1 is treated as negative sign.

Por exemplo: -

1000 0000 0000 0110 = -6 
0000 0000 0000 0110 =  6

Mas na forma de pulso 1 é tratado como positivo e 0 é tão neutro.

         ---   ---   ---
         | |   | |   | |
---------   ---   ---   ---------

Por quê? Existe uma lógica por trás disso?

E é possível tratá-lo de maneira oposta, ou seja, 1 como sinal positivo e 0 como sinal negativo

    
por akash ujjwal 19.01.2015 / 00:58

3 respostas

9

Sua asserção inicial não é realmente verdadeira, não para a grande maioria das arquiteturas de CPU que possuem algo parecido com o uso comum - que usa "aritmética de complemento de dois".

Na aritmética de complemento de 2, se o bit de alta ordem for 1, isso indica um número negativo; mas se o bit de alta ordem for 0, isso não indica um número positivo. Indica não negativo . A diferença é sutil, mas importante. O número pode ser zero ou pode ser positivo.

No complemento de 2, a escala numérica se parece com isso - eu usarei números inteiros de oito bits para simplificar:

binary   signed  unsigned
01111111  127      127
01111110  126      126
 ...
00000011    3        3
00000010    2        2
00000001    1        1
00000000    0        0
11111111   -1      255
11111110   -2      254
 ...
10000010 -126      130
10000001 -127      129
10000000 -128      128

Para negar (inverter aritmeticamente) um número neste sistema, isto é, multiplicá-lo por -1: primeiro você inverte todos os bits e, em seguida, adiciona 1. Então, se começarmos com 1 e invertermos os bits, obtenha 11111110. Adicione 1 e nós temos 11111111. Como acima. Observe que, se fizermos isso novamente, voltaremos para 00000001, como deveríamos.

Os computadores usam esse sistema porque torna a lógica de adição, subtração, etc., aritmética muito simples: A mesma lógica (somadores binários simples; você apenas adiciona todos os bits, incluindo os bits de sinal) funciona para números assinados e não assinados . Observe que adicionar 1 a qualquer número nessa escala leva você à resposta correta ... exceto nos casos de estouro: Adicionar de 1 a 127 resulta em -128, se você estiver interpretando os números como assinados. Mas transborda e transporta e assim por diante são geralmente capturados por sinalizadores de condição ou exceções.

É uma peculiaridade curiosa do complemento de dois que temos mais um número negativo do que positivo ... já que o zero não é nem negativo nem positivo. Portanto, com oito bits, assinados, podemos representar -128, mas não +128. +127 é o maior número positivo. Isso não é um grande problema.

Alguns computadores históricos (séries CDC 3000 e 6000, e alguns mainframes Univac antigos; não conheço exemplos contemporâneos) foram construídos e usaram o "complemento de alguém". Em complemento, para inverter um número, basta virar os bits. Isso resulta em quase a mesma escala acima, exceto que o lado negativo vai de -127 a ... -0! É isso mesmo, em um comp. máquinas, você tem dois zeros: zero positivo e zero negativo. Isso torna a aritmética geralmente mais complicada. Zeros negativos são geralmente convertidos em positivos em algum momento.

Você provavelmente está pensando que deveria ser mais como "magnitude assinada", que é análoga à forma como normalmente escrevemos os números. por exemplo. -2 seria 10000002. Você notará que adicionar 1 a isso não fornece a representação correta de magnitude sinalizada para -1. Dá-lhe -3 em seu lugar. Isso torna a aritmética mais complicada de se fazer, e é por isso que ela não é usada.

    
por 19.01.2015 / 01:32
4

Isso é realmente bastante complicado. Em um nível, a resposta é "porque precisamos de um padrão": se você criar um novo sistema, será muito mais fácil torná-lo da mesma maneira que os sistemas antigos funcionam, para que você possa interagir com esses sistemas antigos com mais facilidade. No entanto, em alguns desses casos, existem razões mais profundas.

Neste post, vou assumir inteiros de oito bits. Os princípios devem funcionar da mesma maneira quando se usa um número diferente de bits.

Pulsos Elétricos

Aqui, com apenas dois valores, não importa qual chamamos de "zero" e que chamamos de "um". Na verdade, não há razão para chamá-los de "zero" e "um". Por exemplo, USB usa “J” e “K” , e alguns dispositivos USB usam a convenção oposta como outros para realmente transmitir o sinal.

Codificação de inteiro

Na verdade, existem várias maneiras de codificar inteiros. Aquele que você mostra em sua pergunta é chamado de "magnitude assinada". Assemelha-se muito ao modo como escrevemos números na vida cotidiana: potencialmente temos um sinal de menos e depois escrevemos o número. Nesse caso, o sinal de menos (ou sinal de mais) é simplesmente o valor do primeiro bit.

No entanto, nem todos os números são assinados. Se eu estiver codificando o número de widgets que minha fábrica fez hoje, quero usar um número não assinado (a menos que eu destrua os widgets na minha fábrica). Nesse caso, seria razoável deixar que 0000 0110 fizesse seis widgets naquele dia.

Se você estiver usando números assinados e não assinados, seria interessante se a conversão entre eles fosse o mais fácil possível. É mais fácil converter se os mesmos bits representam o mesmo número em ambos os casos, portanto, queremos que 0000 0110 signifique seis, mesmo se usarmos um inteiro com sinal. Isso faz com que um 1 seja negativo e um 0 seja positivo.

Complemento de dois

Muito poucos sistemas realmente usam grandeza assinada para inteiros agora, no entanto. A magnitude assinada tem vários problemas, incluindo 0000 0000 e 1000 0000 , o que significa a mesma coisa (zero). Em vez disso, a maioria representa números inteiros assinados usando o que é chamado de "complemento de dois". Ele representa números positivos da mesma maneira (com um zero à esquerda e os outros bits com números não assinados), mas representa números negativos de forma diferente. Com números de oito bits não assinados, o bit mais significativo é o 128s; com dois números de oito bits complementares, é o lugar negativo de 128s. Assim, 1000 0000 é negativo 128, 1000 0001 é negativo 128 + 1 = negativo 127, até 1111 1111 , que é negativo.

Isso pode parecer uma forma estranha de representar números inteiros assinados, mas tem várias vantagens em relação à mais óbvia magnitude sinalizada. Por um lado, ele se livra do problema que mencionei anteriormente de ter duas representações para zero. Por outro lado, você pode adicionar os números usando o mesmo circuito usado para adicionar números não assinados, e isso funcionará corretamente supondo que não haja estouro (e, mesmo se houver estouro, será mais fácil de lidar). Isso não é verdade com magnitude assinada.

Conclusão

Existem várias maneiras possíveis de representarem números assinados ; A magnitude assinada e o complemento de dois são apenas dois dos mais populares. Em certo sentido, não importa qual você usa; você poderia teoricamente inventar seu próprio método não listado lá (ou apenas usar magnitude assinada com o bit de sinal invertido) e fazer computadores inteiros que o usam. No entanto, isso provavelmente não seria uma boa ideia, porque você precisaria converter para um formato diferente se quisesse compartilhar dados com outro computador. Poderíamos ter acabado usando números inteiros de magnitude assinada como nosso padrão (como fizemos para números de ponto flutuante , e então a melhor escolha para a maioria dos novos computadores seria provavelmente fazer a mesma coisa. No entanto, a escolha não foi exatamente arbitrária e há boas razões para que os inteiros positivos usem um zero à esquerda em vez de um líder (como a conformidade com números não assinados).

    
por 19.01.2015 / 01:54
0

É um padrão arbitrário para números inteiros assinados . Observe o byte menor assinado, onde 00000000 a 01111111 são tratados como inteiros positivos, e o bit mais alto, quando definido, os torna negativos, cobrindo o intervalo de -127 a 127 (base 10), com codificação zero com o conjunto de bits à esquerda ou não. Os padrões de bits idênticos também codificam os números unsigned de 0 a 255, por isso é simplesmente um padrão que possibilita aos programadores entender o trabalho dos outros. Consulte link para obter informações sobre a representação numérica assinada.

Você pode inventar seu próprio padrão para números assinados, mas isso gera confusão. Em alguns idiomas, o Boolean True é tratado como 00000001, em outros idiomas (por exemplo, VB) é 10000001 e, em outros, é qualquer valor diferente de zero. Essa é apenas mais uma armadilha para ser cauteloso ao traduzir os idiomas do programa.

    
por 19.01.2015 / 01:30

Tags