Como a maioria das explicações que já vi, as acima são claras sobre como trabalhar com o complemento de 2, mas não explicam realmente o que são matematicamente. Vou tentar fazer isso, pelo menos para números inteiros, e abordarei alguns antecedentes que provavelmente são familiares primeiro.
Lembre-se de como funciona o decimal:
2345
é uma maneira de escrever
2 × 10 3 + 3 × 10 2 + 4 × 10 1 + 5 × 10 0 .
Da mesma forma, binário é uma maneira de escrever números usando apenas 0 e 1 seguindo a mesma idéia geral, mas substituindo os 10s acima por 2s. Então, em binário,
1111
é uma maneira de escrever
1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0
e, se você resolver isso, será igual a 15 (base 10). Isso é porque é
8 + 4 + 2 + 1 = 15.
Tudo está bem para números positivos. Até funciona para números negativos, se você quiser colocar um sinal de menos na frente deles, como os humanos fazem com números decimais. Isso pode até ser feito em computadores, mais ou menos, mas eu não o vejo desde o início dos anos 70. Vou deixar as razões para uma discussão diferente.
Para computadores, é mais eficiente usar um representação de complemento para números negativos. E aqui está algo que geralmente é esquecido. As notações de complemento envolvem algum tipo de reversão dos dígitos do número, mesmo os zeros implícitos anteriores a um número positivo normal. Isso é estranho, porque surge a pergunta: todos eles? Esse pode ser um número infinito de dígitos a serem considerados.
Felizmente, os computadores não representam infinitos. Os números são restritos a um comprimento específico (ou largura, se você preferir). Então, vamos voltar aos números binários positivos, mas com um tamanho específico. Vou usar 8 dígitos ("bits") para esses exemplos. Portanto, nosso número binário seria realmente
00001111
ou
0 × 2 7 + 0 × 2 6 + 0 × 2 5 + 0 × 2 4 + 1 × 2 3 + 1 × 2 2 + 1 × 2 1 + 1 × 2 0
Para formar o complemento 2 negativo, primeiro complementamos todos os dígitos (binários) para formar
11110000
e adicionamos 1 ao formulário
11110001,
mas como devemos entender isso como -15?
A resposta é que mudamos o significado do bit de ordem superior (o mais à esquerda). Este bit será 1 para todos os números negativos. A mudança será alterar o sinal de sua contribuição para o valor do número em que aparece. Portanto, agora nosso 11110001 é entendido como representando
- 1 × 2 7 + 1 × 2 6 + 1 × 2 5 + 1 × 2 4 + 0 × 2 3 + 0 × 2 2 + 0 × 2 1 + 1 × 2 0
Percebe que "-" na frente dessa expressão? Isso significa que o bit de sinal carrega o peso -2 7 , ou seja, -128 (base 10). Todas as outras posições mantêm o mesmo peso que tinham em números binários não assinados.
Calculando -15, é
-128 + 64 + 32 + 16 + 1
Experimente na sua calculadora. é -15.
Das três principais maneiras pelas quais eu vi números negativos representados em computadores, o complemento do 2 ganha as mãos por conveniência em uso geral. Tem uma estranheza, no entanto. Por ser binário, deve haver um número par de combinações de bits possíveis. Cada número positivo pode ser emparelhado com seu negativo, mas há apenas um zero. Negar um zero leva a zero. Portanto, há mais uma combinação, o número com 1 no bit de sinal e 0 em qualquer outro lugar. O número positivo correspondente não caberia no número de bits que está sendo usado.
O que é ainda mais estranho nesse número é que, se você tentar formar um positivo complementando e adicionando um, receberá o mesmo número negativo. Parece natural que o zero faça isso, mas isso é inesperado e não é de todo o comportamento a que estamos acostumados, porque os computadores à parte, geralmente pensamos em um suprimento ilimitado de dígitos, não nessa aritmética de comprimento fixo.
É como a ponta de um iceberg de esquisitices. Há mais espera abaixo da superfície, mas isso é suficiente para esta discussão. Você provavelmente poderá encontrar mais se pesquisar "estouro" de aritmética de ponto fixo. Se você realmente quiser entrar nele, também pode pesquisar "aritmética modular".