O que é10? Se esta é a primeira vez que você aprende sobre o sistema numérico binário, esta pergunta pode parecer estranha. Claro que são dez, certo?
Vamos tentar algo diferente. Você já ouviu essa piada?
Há10tipos de pessoas: aquelas que entendem binário e aquelas que não entendem.
A menos que você esteja familiarizado com números binários, isso provavelmente não faz muito sentido. Mas, ao final deste artigo, você entenderá essa piada horrível!
Neste tutorial para iniciantes, veremos tudo o que você precisa saber sobre o sistema numérico binário, mas também daremos uma olhada rápida em decimal e hexadecimal, pois estão intimamente relacionados. Incluirei trechos de código relevantes e exemplos da vida real para ajudá-lo a apreciar a beleza do binário.
Pular índice
Índice
O que é um sistema numérico?
Antes de olharmos para o binário, vamos dar um passo atrás e discutir os sistemas numéricos de forma mais geral.
Pode parecer estranho pensar em númerosistemasno plural, se esta for a primeira vez que você está aprendendo sobre eles. Isso porque a maior parte do mundo está familiarizada com apenas um sistema: osistema numérico decimal, também conhecido comoSistema numérico árabe. Este sistema numérico usa os dígitos0–9para representar números simbolicamente, com base em sua posição em uma string.
Por exemplo, no sistema numérico decimal,579se expande para isso:
579=5(102)+7(101)+9(100)=500+70+9
Na escola, você aprendeu que o5em579está na centésima casa, o7está na casa das dezenas e o9está no lugar das unidades. Observe que o5é multiplicado por cem (102), o7às dez (101), e a9por um (100) para formar o número decimal579. Dizemos que o número579éposicionalporque os dígitos, da esquerda para a direita, correspondem a uma potência específica de dez com base na posição do dígito no número.
Aqui, o número10é o que chamamos debase(também conhecido comoraiz) do nosso sistema numérico. Observe os poderes de10na expressão expandida acima:102,101, e100. Por esta razão, os termosdecimalebase dezsão intercambiáveis.
No sistema de numeração decimal, um número é representado colocando dígitos em “baldes” que representampotências crescentes de dez, começando com100no “balde” mais à direita, seguido por101imediatamente à sua esquerda e assim por diante infinitamente:
Quaisquer buckets não utilizados na extrema esquerda têm um valor implícito de0neles. Geralmente cortamos os zeros à esquerda porque não adianta dizer00579quando isso é matematicamente idêntico a579.
Por que os humanos escolheram10ser a base do seu sistema numérico preferido? Provavelmente porque a maioria das pessoas nasce com dez dedos nas mãos e nos pés, e estamos acostumados a contar com os dedos quando somos jovens. Portanto, é natural que tenhamos adotado dez como base do nosso sistema numérico.
Bases, expoentes e dígitos
Como já sugeri, o sistema numérico decimal (base10) não é o único que existe. Vamos utilizar uma notação mais geral para representar sistemas numéricos além do nosso familiar.
Num sistema numérico com base fixa deb, os dígitos disponíveis variam de0parab-1. Por exemplo, no sistema numérico decimal (b=10), só podemos usar os dígitos0,1,2,...,9. Quando você fica sem dígitos para colocar em um único balde, você transfere um para a próxima potência da base. Por exemplo, para chegar ao número depois99, você carrega um para o balde representando a próxima potência de dez (100).
Agora, suponha que temos uma sequência de dígitosdn-1dn-2...d0(ondené o número de dígitos). Talvez seja issod2d1d0=579do nosso exemplo anterior. Essa string se expande assim:
dn-1bn-1+dn-2bn-2+...+d0b0
E você pode visualizar assim:
Usando nosso mesmo exemplo,dn-1bn-1+dn-2bn-2+...+d0b0=5(102)+7(101)+9(100). Novamente, temos baldes da direita para a esquerda em potências crescentes de nossa base (10), conforme ilustrado abaixo:
Agora, na realidade, você pode ter um sistema numérico que usa uma base de2,3,4,120, e assim por diante. Alguns deles têm nomes especiais porque são usados com mais frequência do que outros:
Base | Nome | Descrição |
---|---|---|
1 | Unário | Também conhecido como contagem. Um númeron é representado escolhendo um caractere arbitrário e repetindo-on vezes (por exemplo,xxxx seria4 ). |
2 | Binário | Apenas dois dígitos: zero e um. Mais comumente usado em computação. Tudo em um computador é, no nível mais baixo possível, armazenado usando o sistema numérico binário. |
8 | octal | Apenas oito dígitos estão disponíveis:0–7 . |
16 | Hexadecimal | Quinze dígitos:0–9 ea-f . Freqüentemente usado para expressar strings binárias de forma mais compacta. |
60 | sexagesimal | Quantos segundos tem um minuto? Quantos minutos em uma hora? Esta é a base do moderno sistema de coordenadas circulares (graus, minutos e segundos). |
Por esta razão, quando discutimos sistemas numéricos, normalmente subscrevemos um número à sua base para esclarecer o seu valor. Alternativamente, você pode preceder um número com uma determinada string (geralmente0b
para binário ou0x
/#
para hexadecimal). Então nós escreveríamos579como57910, ou o número binário1001como10012(ou0b1001). Caso contrário, se apenas escrevêssemos o número1001sem fornecer qualquer contexto, ninguém saberia se está em binário, octal, decimal, hexadecimal e assim por diante, porque os dígitos0e1também são válidos em todos esses sistemas numéricos!
O sistema numérico binário
Todos estamos familiarizados com os números decimais porque os usamos todos os dias. Mas e o sistema numérico binário?
Por definição, osistema numérico bináriotem uma base de2, e assim só podemos trabalhar com dois algarismos para compor números:0e1. Tecnicamente falando, não chamamos esses dígitos – eles são chamadospedaçosem linguagem binária. Cada “balde” em uma string binária representa uma potência crescente de dois:20,21,22, e assim por diante.
O bit mais à esquerda é chamado debit mais significativo (MSB), enquanto o bit mais à direita é chamado debit menos significativo (LSB).
Aqui estão alguns exemplos de representação de números decimais no sistema numérico binário:
- Zero:010=02. Expansão:0(20)
- Um:110=12. Expansão:1(20)
- Dois:210=102. Expansão:1(21)+0(20)
- Três:310=112. Expansão:1(21)+1(20)
- Quatro:410=1002. Expansão:1(22)+0(21)+0(20)
- Cinco:510=1012. Expansão:1(22)+0(21)+1(20)
Tendo aprendido o sistema numérico binário, agora você deve entender a piada anterior:
Há10tipos de pessoas: aquelas que entendem binário e aquelas que não entendem.
Aqui, realmente queremos dizer o equivalente binário de dois, quevisualcomo dez aos nossos olhos quando não está devidamente subscrito:102=1×21=210.
O binário está próximo do hardware de um computador
Por que nos preocupamos em usar o sistema numérico binário em primeiro lugar? Não parece muito trabalho extra representar números desta maneira quando poderíamos usar o sistema numérico decimal? Bem, sim - se você estiver escrevendo à mão, certamente será mais trabalhoso representar (e manipular) números binários.
Você pode não ver sentido em usar binário se não tiver aprendido sobre arquitetura de computadores em um nível baixo. Internamente, os computadores nada mais são do que circuitos elétricos ligados ao hardware. A corrente flui através de um fio ou não – umestado binário. Da mesma forma, os computadores usamportas lógicas(AND/OR/NOR/XOR) para controlar o fluxo de execução de um programa, e estes recebem entradas binárias (verdadeiro
/falso
). A melhor maneira de representar essas interações de baixo nível é usar o sistema numérico binário:0significa “desligado” (oufalso
em sua forma booleana) e1significa “ligado” (verdadeiro
).
Tudo no seu computador – os arquivos que você salva e o software que você instala – é representado como nada mais do que zeros e uns. Mas como isso é possível?
O padrão Unicode
Suponha que você crie um arquivo em seu computador e armazene nele algum texto básico:
ecoOlá, binário> arquivo
No final das contas, seu computador não consegue armazenar um caractere comoH
,e
,eu
, ouó
(ou mesmo o espaço entre duas palavras)literalmente. Os computadores só sabem trabalhar combinário. Portanto, precisamos de alguma forma de converter esses caracteres em números. E é por isso que o padrão Unicode foi introduzido.
Unicode é o mais amplamente aceitopadrão de codificação de caracteres: um método de representar caracteres legíveis por humanos comoH
,e
,,
,?
, e9
numericamente para que os computadores possam entendê-los e usá-los como nós. Cada caractere é mapeado para um número exclusivo conhecido comoponto de código.
Por exemplo, o gráfico abaixo mostra um subconjunto muito limitado de caracteres Unicode (conhecido como padrão ASCII) e seus pontos de código correspondentes:
Por uma questão de brevidade, vamos nos concentrar apenas no padrão ASCII por enquanto, mesmo que ele não capture toda a gama de caracteres do padrão Unicode e as complexidades que advêm da necessidade de suportar centenas de milhares de caracteres.
O padrão ASCII suporta apenas 128 caracteres, cada um mapeado para um número exclusivo:
- Dígitos árabes:0-9(10)
- Letras latinas maiúsculas:A-Z(26)
- Letras latinas minúsculas:a-z(26)
- Pontuação e caracteres especiais (66)
Novamente, observe que, embora o padrão ASCII nos permita representar apenas uma pequena fração de caracteres Unicode, ele é simples o suficiente para nos ajudar a entender melhor como os caracteres são armazenados nos computadores.
1 caractere ASCII = 1 byte
No sistema numérico decimal, estamos acostumados a trabalhar com dígitos. Em binário, como já vimos, estamos acostumados a trabalhar compedaços. Há outro grupo especial de dígitos em binário que vale a pena mencionar: uma sequência de oito bits é chamada debyte.
Aqui estão alguns exemplos de bytes válidos:
00000000100000001110101111111111
… e qualquer outra permutação válida de oito0areia1é isso que você pode pensar.
Por que isso é relevante? Porque nos computadores modernos,caracteres são representados usando bytes.
Lembre-se de que o formato de codificação ASCII precisa suportar um total de128 caracteres. Então, quantos números únicos podemos representar com8bits (um byte)?
Bem, usando a regra do produto da combinatória, temos oito “baldes”, cada um com dois valores possíveis: ou um0ou um1. Assim, temos2×2×...×2=28valores possíveis.
Em decimal, isso é28=256valores possíveis. Por comparação,27=128. E128passa a ser o número de caracteres que queremos representar.
Então… Isso é estranho e aparentemente um desperdício, certo? Por que usamos8bits (um byte) para representar um caractere quando poderíamos usar7bits e atender à contagem precisa de caracteres que precisamos?
Boa pergunta! Usamos bytes porquenão é possível dividir igualmente um grupo de7pedaços, dificultando certos cálculos de baixo nível se decidirmos usar7bits para representar um caractere. Em contraste, um byte pode ser dividido igualmente em potências de dois:
11101011[1110][1011][11][10][10][11]
A principal conclusão aqui é que precisamos apenas de um byte para armazenar um caractere em um computador. Isso significa que uma sequência de cinco caracteres - comoOlá
—ocupa cinco bytes de espaço, sendo cada byte a representação numérica do caractere correspondente no formato ASCII.
Lembra do arquivo que criamos anteriormente? Vamos ver sua representação binária usando oxxd
Ferramenta Unix:
xxd-b arquivo
O-b
flag significa binário. Aqui está o resultado que você obterá:
00000000: 01001000 01100101 01101100 01101100 01101111 00101100 Olá, 00000006: 00100000 01000010 01101001 01101110 01100001 110010 Binar0000000c: 01111001 00001010 y.
A primeira linha mostra uma sequência de seis bytes, cada um correspondendo a um caractere emOlá,
.
Vamos decodificar os dois primeiros bytes usando nosso conhecimento do sistema numérico binário e ASCII:
- 01001000=1(26)+1(23)=7210. De acordo com nossa tabela ASCII, isso corresponde aH.
- 01100101=1(26)+1(25)+1(22)+1(20)=10110, qual éeem ASCII.
Legal! Parece que a lógica dá certo. Você também pode repetir isso para todos os outros bytes. Observe que na segunda linha, temos um espaço inicial (deOlá, binário
), representado como25=3210em ASCII (que é de fatoEspaço
conforme a tabela).
A propósito, o que há com os números no lado esquerdo da saída? O que0000000cmesmo significa? É hora de explorar outro sistema numérico importante!
O sistema numérico hexadêmico
Como mencionei na tabela anterior, o sistema numérico hexadecimal está intimamente relacionado ao binário porque é frequentemente usado para expressar números binários de forma mais compacta, em vez de escrever um monte de zeros e uns.
Osistema numérico hexadecimaltem uma base de16, o que significa que seus dígitos variam de0–15.
Esta é a primeira vez que encontramos um sistema numérico cujos dígitos são compostos por mais de dois caracteres. Como podemos apertar10,11, ou15em um único “balde” ou “slot” para um dígito? Para ser claro,isso é perfeitamente factívelse você tiver delimitadores claros entre dígitos, como linhas verticais - sem os quais você não saberia se15é um seguido por cinco ou um único dígito de15naqueles lugares. Mas, na realidade, usar delimitadores não é prático.
Vamos dar um passo atrás e considerar um número hexadecimal simples:
0x42
O que isso significa para nós, humanos, em nosso sistema numérico decimal? Bem, tudo o que precisamos fazer é multiplicar cada dígito pela sua potência correspondente de16:
0x42=4(161)+2(160)=6410+210=6610
Ok, então esse é um número hexadecimal simples. De volta ao problema em questão: como representamos os dígitos hexadecimais10,11, e assim por diante? Aqui está um exemplo que é bastante confuso, a menos que introduzamos alguma notação alternativa:
0x15
Isso é um15em um único slot ou em um1e um5em dois slots separados? Uma maneira de tornar isso menos ambíguo é usar algum tipo de delimitador entre slots, mas, novamente, isso não é muito prático:
0x8[15]29
A melhor solução que as pessoas encontraram foi mapear10–15para as letras inglesasa–f. Observe que também poderíamos ter usado quaisquer outros símbolos para representar esses algarismos. Contanto que concordemos com uma convenção e a cumpramos, não haverá ambigüidade quanto ao que um número representa.
Aqui está um exemplo de número hexadecimal que usa um destes dígitos:
0xf4
E aqui está sua expansão:
0xf4=15(161)+4(160)=24010+410=24410
Não há nada de mágico no sistema numérico hexadecimal – ele funciona como unário, binário, decimal e outros. A única diferença é a base!
Antes de prosseguirmos, vamos revisitar a saída anterior, quando usamosxxd
em nosso arquivo de amostra:
00000000: 01001000 01100101 01101100 01101100 01101111 00101100 Olá, 00000006: 00100000 01000010 01101001 01101110 01100001 110010 Binar0000000c: 01111001 00001010 y.
Os números no lado esquerdo marcam o byte inicial de cada linha de texto na extremidade direita. Por exemplo, a primeira linha do texto (Olá,
) varia do byte #0 (H
) para o byte #5 (,
). A próxima linha é marcada como00000006, o que significa que agora estamos olhando para os bytes 6 a 11 (B
paraR
). Finalmente, o último rótulo deve fazer sentido agora que você conhece o sistema numérico hexadecimal:c
mapas para12, significando que o byte a seguir corresponde ao décimo segundo caractere em nosso arquivo.
Como converter entre binário e hexadecimal
Agora que sabemos um pouco sobre binário e hexadecimal, vamos ver como podemos converter entre os dois sistemas.
Binário para Hexadecimal
Digamos que você receba esta string binária e queira representá-la em hexadecimal:
011011100101
Embora à primeira vista possa parecer uma tarefa bastante difícil, na verdade é simples!
Vamos fazer um pequeno exercício de reflexão: no sistema numérico hexadecimal, temos16dígitos de0para15. Na terra binária, quantos bits precisamos para representar esses16valores?
A resposta é quatro porque24=16. Com quatro “baldes”, podemos criar os números zero (0000), um (0001), dez (1010), até quinze (1111). Isso significa que quando você recebe uma string binária, tudo que você precisa fazer édivida-o em grupos de quatro bitse avalie-os para converter binário em hexadecimal!
011011100101[0110][1110][0101]6 14 5
Agora é só substituir10–15coma-fe terminamos:0x6e5.
Hexadecimal para Binário
E o processo inverso? Como você converte um número hexadecimal em binário? Digamos que você receba o número hexadecimal0xad. O que sabemos sobre cada dígito hexadecimal?
Bem, do nosso exercício anterior, sabemos que quatro bits constituem um dígito hexadecimal. Portanto, podemos converter cada dígito hexadecimal individual em seu4representação de bits e, em seguida, junte cada grupo!
a16=1010=10102d16=1310=11012ad16=101011012
Aplicação no mundo real: cores em RGB/Hex
Embora estejamos no tópico binário e hexadecimal, vale a pena dar uma olhada em um caso de uso do mundo real para o que aprendemos até agora:Cores RGB e hexadecimais.
As cores têm três componentes: vermelho, verde e azul (RGB). Com telas de LED (diodo emissor de luz), cada pixel é realmente dividido nesses três componentes usando um diodo colorido. Se um componente de cor estiver definido como0, então ele está efetivamente desligado. Caso contrário, sua intensidade é modulada entre0e255, dando-nos um formato de cor comorgb(0-255, 0-255, 0-255)
.
Vamos considerar esta cor hexadecimal:#4287f5
. O que há no formato RGB?
Bem, precisamos dividir esta sequência hexadecimal igualmente entre vermelho, verde e azul. São dois dígitos por cor:
[42][87][f5]
Agora, interpretamos o equivalente decimal para cada parte:
- Vermelho:4216=4(161)+2(160)=66
- Verde:8716=8(161)+7(160)=135
- Azul:f516=15(161)+5(160)=245
Que significa#4287f5
é realmentergb(66, 135, 245)
! Você pode verificar isso usando umConversor de cores:
Para praticar, vamos converter isso para binário também. Vou marcar os grupos de quatro bits para ficar mais fácil de ver como fiz isso (você também pode converter da representação RGB decimal se quiser):
0x4287f5=0b[0100][0010][1000][0111][1111][0101]
Agora, dois grupos de quatro bits representarão um componente da cor (vermelho/verde/azul):
0b[01000010][10000111][11110101]
Observe que cada corcomponenteocupa um byte (8bits) de espaço.
Quantas cores existem?
Como exercício adicional, quantas cores exclusivas você pode ter no formato RGB moderno?
Sabemos que cada componente (vermelho/verde/azul) é representado usando um byte (8pedaços). Então as cores com as quais estamos acostumados são realmente24-bit cores.
Isso significa que há uma enorme224=16,777,216possíveis cores exclusivas que você pode gerar usando hex/rgb! O24O sistema de cores de bits é conhecido comocor verdadeira, e é capaz de representar milhões de cores.
Observe que você poderia muito bem ter realizado este cálculo usando hexadecimal:#4287f5
. Existem seis slots, cada um capaz de assumir um valor de0paraf. Isso nos dá um total de16×16×...×16=166=16,777,216valores - o mesmo resultado de antes.
Ou, se você estiver usando o formato RGB decimal, a matemática ainda funciona:
256×256×256=16,777,216
O que são cores de 8 bits?
Em sistemas mais antigos com memória limitada, as cores eram representadas usando apenas oito bits (um byte). EssesCores de 8 bitstinha uma paleta muito limitada, o que significava que a maioria dos gráficos de computador não tinha transições graduais de cores (portanto, as imagens pareciam muito pixelizadas/granuladas). Com apenas8bits para trabalhar, você está limitado a apenas28=256cores!
Naturalmente, você deve estar se perguntando: como eles se separaram8bits uniformemente entre vermelho, verde e azul? Afinal,8não é divisível por três!
Bem, a resposta é queeles não. O processo de divisão desses bits entre os componentes da cor é chamadoquantização de cores, e o método mais comum (conhecido comoCor verdadeira de 8 bits) divida os bits como 3-3-2 vermelho-verde-azul. Aparentemente, isso ocorre porque o olho humano é menos sensível à luz azul do que os outros dois e, portanto, simplesmente fazia sentido distribuir fortemente os bits em favor do vermelho e do verde e deixar o azul com um bit a menos para trabalhar.
Sistema de números binários assinados: complemento de dois
Agora que cobrimos decimal, binário e hexadecimal, gostaria que revisitássemos o sistema numérico binário e aprendêssemos como representar números negativos. Porque até agora, analisamos apenas números positivos. Como armazenamos o sinal negativo?
Para nos dar algum contexto, assumirei que estamos trabalhando com padrões32inteiros de bits que a maioria dos computadores suporta. Poderíamos muito bem olhar64-bit ouNinteiros de bits, mas é bom ter uma base simples para uma discussão.
Se tiver-mos32bits para mexer, isso significa que podemos representar um total de232=4,294,967,296(4 bilhões) números. De forma mais geral, se você tiverNbits para trabalhar, você pode representar2Nvalores. Mas gostaríamos de dividir este intervalo de números igualmente entre negativos e positivos.
Positivo ou negativo… positivo ou negativo. Uma coisa ou outra – lembra alguma coisa? Parece que é de natureza binária. E ei, já estamos usando binário paralojanossos números! Por que não reservar apenas um bit para representaro sinal? Podemos fazer com que o bit mais significativo (principal) seja um0quando nosso número é positivo e um1quando é negativo!
Anteriormente, quando examinamos pela primeira vez os sistemas numéricos binários, mencionei que você pode retirar os zeros iniciais porque eles não têm sentido. Isso é verdade, exceto quando você realmente se preocupa em distinguir entre números positivos e negativos em binário. Agora, precisamos ter cuidado - se você retirar todos os zeros iniciais, poderá ficar com um zero inicial1, e isso implicaria que seu número é negativo (em um sistema numérico assinado).
Você pode pensar no complemento de dois como um novoperspectivaou lente através da qual olhamos para os números binários. O número1002normalmente significa410se não nos importamos com o seu sinal (ou seja, assumimos que énão assinado). Mas se nos importamos, temos que perguntar a nós mesmos (ou a quem nos forneceu esse número) se é um número assinado.
Como funciona o complemento de dois?
O que um líder1na verdade representa quando você expande um número binário assinado, e como convertemos um número positivo em um negativo e vice-versa? Por exemplo, suponha que estamos olhando para o número2210, que é representado assim em binário não assinado:
101102
Como estamos analisando um binário assinado, precisamos preencher esse número com um valor extra0na frente (ou então um líder1implicaria que é negativo):
0101102
Ok, então isso é positivo2210. Como representamos-2210em binário?
Existem duas maneiras de fazer isso: a abordagem intuitiva (mais longa) e a abordagem de “atalho”. Vou mostrar os dois, mas começarei pelo mais intuitivo.
A abordagem intuitiva: o que significa um líder 1?
Dado umNstring binária de -bit, um líder1em complemento de dois representa-1multiplicado por sua potência correspondente de dois (2n-1). Um dígito de1em qualquer outro slot representa+1vezes a sua potência correspondente de dois.
Por exemplo, o número assinado110102tem esta expansão:
110102=-1(24)+1(23)+1(21)=-1610+810+210=-610
Nós simplesmente tratamos o líder1como negativo, e isso altera a soma resultante em nossa expansão.
Atalho de complemento de dois: inverta os bits e adicione 1
Para converter um número representado em binário em complemento de dois em seu sinal oposto, siga estas duas etapas simples:
- Vire todos os bits (0torna-se1e vice versa).
- Adicionar1para o resultado.
Por exemplo, vamos converter4310para-4310em binário:
+43 em binário: 0101011Invertido: 1010100Adicione um: 1010101
Qual é esse número? Deveria ser-4310, então vamos expandi-lo manualmente para verificar:
-1(26)+1(24)+1(22)+1(20)=-6410+1610+410+110=-43
Com certeza, o processo funciona!
Quantos números binários assinados existem?
Vimos que num sistema binário com sinal, o bit mais significativo é reservado para o sinal. O que isso faz com nosso intervalo de números? Efetivamente, reduz pela metade!
Vamos considerar32inteiros de -bit novamente. Considerando que antes tínhamos32bits para trabalhar para a magnitude de um número sem sinal, agora temos apenas31para a magnitude de um número assinado (porque o 32º bit está reservado para o sinal):
Bits de magnitude sem sinal: [31 30 29 ... 0]Bits de magnitude com sinal: 31 [30 29 ... 0]
Passamos de ter232números para231números positivos e negativos, que é precisamente metade do que começamos (2232=231).
De modo mais geral, se você tiver umN-bit string binária assinada, haverá2Nvalores, divididos igualmente entre2n-1positivos e2n-1negativos.
Observe que o número zero fica agrupado com os positivos e não com os negativos:
Zero assinado: 0 0 0 0 ... 0 0 0 0Bits: 31 30 29 28 ... 3 2 1 0
Como veremos, isso tem uma consequência interessante.
Qual é o maior número inteiro assinado de 32 bits?
O maior inteiro assinado de 32 bits é positivo, o que significa que seu bit inicial é zero. Então só precisamos maximizar os bits restantes para obter o maior valor possível:
Número: 0 1 1 1 ... 1Bits: 31 30 29 28 ... 0
Isso é231-1, qual é2,147,483,647. Em Java, esse número é armazenado emInteiro.MAX_VALUE
, e em C++, éstd::numeric_limits
.
Mais genericamente, para umNsistema de bits, o maior inteiro assinado é2n-1-1.
Por que subtraímos um no final? Porque começamos a contar em um, mas os computadores começam em zero. Como mencionei na seção anterior, o número zero é agrupado junto com os positivos quando dividimos nosso intervalo numérico (por convenção):
Zero assinado: 0 0 0 0 ... 0 0 0 0Bits: 31 30 29 28 ... 3 2 1 0
Portanto, para obter o maior número inteiro com sinal, precisamos subtrair um.
Aplicação no mundo real: moeda de videogame
Em videogames como RuneScape que usam32Números inteiros assinados de -bit para representar a moeda do jogo, a “pilha de dinheiro” máxima que você pode definir exatamente231-1, que é cerca de 2,1 bilhões.
Agora você sabe por quê! Se você está se perguntando por que eles não usam unsigned ints, é porque o RuneScape roda em Java, eJava não suporta entradas não assinadas(exceto em SE 8+).
Qual é o menor número inteiro assinado de 32 bits?
Isso ocorre quando definimos o bit inicial como um1e defina todos os bits restantes como um0:
Número: 1 0 0 0 ... 0 Bits: 31 30 29 28 ... 0
Por que? Porque lembre-se de que na expansão de números negativos em complemento de dois binário, o líder1é um-1vezes2n-1, e um1em qualquer outra posição será tratado como+1vezes a sua potência correspondente de dois. Como queremos o menor número negativo, não queremos quaisquer termos positivos, pois estes diminuem a nossa magnitude. Então definimos todos os bits restantes como0.
Responder:-231
Em Java, esse valor é armazenado emInteiro.MIN_VALUE
. Em C++, está emstd::numeric_limits
.
De modo mais geral, se tivermos umaNsistema de bits, o menor int assinado representável é-2n-1.
Observe que a magnitude do menor sinal32-bit inteiro é exatamente um maior que a magnitude do maior sinal32número inteiro de bits. Conforme mencionado anteriormente, isso se deve ao local onde escolhemos agrupar o próprio número zero, que “rouba” uma magnitude dos bits disponíveis desse grupo.
Aritmética Binária
Spoiler: Adicionar, subtrair, multiplicar e dividir números no sistema numérico binário éexatamente o mesmocomo está em decimal!
Adicionando Números Binários
Primeiro, revisitaremos o que aprendemos na escola primária sobre números decimais e, em seguida, veremos como adicionar dois números binários.
Para adicionar dois números no sistema numérico decimal, você os empilha visualmente e trabalha da direita para a esquerda, adicionando dois dígitos e “carregando aquele” conforme necessário.
Agora você deve saber o que realmente significa carregar aquele: quando você fica sem dígitos para representar algo em seu sistema numérico de base fixa (por exemplo,13não é um dígito na base10), você representa a parte que pode na posição dos dígitos atuais e passa para a próxima potência da sua base (a “coluna” à esquerda da sua base atual).
Por exemplo, vamos adicionar24e18em decimal:
24+ 18———— 42
Primeiro adicionamos o4e8obter12, que não é um dígito compatível com o sistema numérico decimal. Então representamos a parte que podemos (2) e leve o valor restante (dez) para a próxima coluna como um1(1×101=1010). Nessa coluna, temos110+210+110=410:
1 <-- carregado 24 + 18———————— 42
Agora, vamos adicionar esses mesmos dois números (2410e1810) usando o sistema numérico binário:
11000+ 10010——————— 101010
Trabalhamos da direita para a esquerda:
- Um lugar:0+0=0
- Lugar dois:0+1=1
- Lugar de quatro:0+0=0
- Oitavo lugar:1+0=1
- Dezesseis lugares:1+1=102(dois)
Este último passo merece alguns esclarecimentos: quando tentamos somar os dois, obtemos12+12=102(dois), então colocamos um0na coluna atual e transferir o1para a próxima potência de dois, onde temos vários zeros à esquerda implícitos:
1 <- transportar bits0000 ... 000110000000 ... + 00010010—————————————0000 ... 00101010
Nessa coluna,1(caRReued)+0(eueupeueuceut)=1.
Se expandirmos o resultado, descobriremos que é a mesma resposta que obtivemos em decimal:
1(25)+1(23)+1(21)=32+8+2=4210
Vejamos mais um exemplo para nos sentirmos confortáveis com o transporte de bits na adição binária:2210+1410, que sabemos ser3610:
10110+ 01110——————— 100100
Algo interessante acontece quando olhamos para o lugar dos dois (o21coluna): adicionamos12para12, nos dando dois (102), então colocamos um zero no21coluna e carregue a restante.
Agora temos três unidades no22coluna:12(caRReued)+12(ópeRand1)+12(ópeRand2)=112(três). Então colocamos um no22coluna e carregue uma mais uma vez. Enxague e repita!
1111 <- transportar bits0000 ... 000101100000 ... + 00001110——————————0000 ... 00100100
Mais uma vez, é uma boa prática expandir o resultado para que você possa verificar seu trabalho:
1(25)+1(22)=3210+410=3610
Subtraindo Números Binários
Subtração é adição com operando negativo:a-b=a+(-b). Agora que sabemos como representar números negativos no sistema binário graças ao complemento de dois, isso deve ser moleza:negue o segundo operando e execute a adição.
Por exemplo, o que é1210-2610? Em decimal, sabemos que isso é-1410. Em binário, sabemos que1210é01100. A respeito-2610? Representaremos isso usando o complemento de dois.
Começamos representando primeiro2610em binário:
+2610=0110102
Agora negamos invertendo os bits e adicionando um:
26 em binário: 011010Invertido: 100101Adicione um: 100110 = -26
Em seguida, empilhe os operandos e adicione-os como antes:
11 <- transportar bits 001100 + 100110————————— 110010
Observe que o resultado tem um número inicial, que sabemos que denota um número negativo em binário assinado. Então pelo menos acertamos a parte da sinalização! Vamos verificar a magnitude:
-1(25)+1(24)+1(21)=-3210+1610+210=-1410
Adicionar e subtrair números no sistema numérico binário não é diferente do sistema decimal! Estamos apenas trabalhando com bits em vez de dígitos.
Multiplicando Números Binários
Vamos nos lembrar de como multiplicamos números em decimais:
21x12————
Lembra do processo? Nós multiplicamos o2por cada dígito do primeiro multiplicando e escreva o resultado abaixo da barra:
21x 12———— 42
Então passamos para o1em12e repita o processo, mas adicionando um0na coluna direita do resultado. Adicione os dois produtos intermediários para obter a resposta:
21x 12————— 42+ 210————— 252
Adivinha? O processo é exatamente o mesmo no sistema numérico binário!
Vamos multiplicar esses mesmos dois números em binário. Eles são2110=010101e1210=01100:
010101x 01100—————————
Obviamente, isso estará mais envolvido em binário, já que estamos trabalhando com bits (e, portanto, strings mais longas), mas a lógica ainda é a mesma. Na verdade, além de ter que escrever tantos resultados intermediários, na verdade é muito mais fácil fazer isso em binário. Sempre que um dígito é1, você simplesmente copia o primeiro multiplicando, preenchido com zeros. Sempre que for zero vezes o primeiro multiplicando, o resultado será zero!
010101x 01100———————————— 000000 0000000 01010100 010101000+ 0000000000——————————— 0011111100
Expandindo isso em binário, obtemos:
00111111002=1(27)+1(26)+1(25)+1(24)+1(23)+1(22)=25210
Mole-mole. O mesmo processo se aplica independentemente de seus multiplicandos serem assinados ou não.
Divisão de números binários
Vamos dividir12610por1210usando divisão longa:
0 1 0 . 5 _______12 |1 2 6 - 1 2 ———— 0 6 - 0 —————— 6 0 - 6 0 ————— 0
Responder:10.5.
Agora vamos repetir o processo no sistema numérico binário. Observe que vou retirar os zeros à esquerda para facilitar minha vida, já que estamos trabalhando com dois números sem sinal:
_______1100 |1111110
Considere as coisas um dígito de cada vez efaça referência a este vídeo útil do YouTubese você ficar preso:
0 0 0 1 0 1 0 . 1 ______________1 1 0 0 |1 1 1 1 1 1 0 . 0 -0 —— 1 1 - 0 ———— 1 1 1 - 0 —————— 1 1 1 1 - 1 1 0 0 ———————— 1 1 1 - 0 ———— —————— 1 1 1 1 - 1 1 0 0 ————————— 0 0 1 1 0 - 0 ————————— 1 1 0 - 0 ————— 1 1 0 0 - 1 1 0 0 ——————— 0 0 0 0
Responder:01010.1.
O que faz o1à direita da vírgula representa? Bem, no sistema numérico decimal, qualquer coisa à direita da vírgula decimal representa uma potência negativa de dez:10-1,10-2, e assim por diante.
Como você deve ter adivinhado, no sistema numérico binário, estes são2-1,2-2, e assim por diante. Então.1acima realmente significa1(2-1), qual é21=0.510em decimal. E, claro, a parte na frente da vírgula decimal é avaliada como1010.
Isso nos dá1010+0.510=10.5. Portanto, nossa resposta usando divisão binária longa éexatamente o mesmocomo aquele que superamos em decimal!
Overflow e Underflow de números inteiros em binário
O que acontece se você tentar adicionar um ao maior representávelN-bit inteiro assinado?
Por exemplo, seN=32, estamos realmente perguntando o que acontece se tentarmos adicionar um ao maior representável32-bit assinado int.
Vamos tentar:
0111...11111 + 0000...00001—————————
Na coluna mais à direita, obteremos12+12=102, então isso é um zero e um um. Mas, como resultado, todas as adições restantes serão12+12já que sempre carregaremos um até chegarmos à parte inicial:
11111111111 <- transportar bits 0111...11111 (2^{N-1} - 1) + 0000...00001 (1)——————————————— 1000.. 0,00000 (-2^{N-1})
E que número é esse em binário assinado? Hmm… Parece que é o menor número negativo representável! O que observamos aqui é chamadoestouro de número inteiro. Quando você tenta ultrapassar o maior inteiro assinado representável em um determinadoNsistema de bits, o resultadotransbordaouenvolve.
E se tentarmos subtrair um do menor representávelN-bit inteiro assinado? Primeiro, representaremos-110como um número inteiro assinado em binário:
1 em binário: 0000...00001Invertido: 1111...11110Adicione um: 1111...11111 <-- -1
Agora vamos adicionar isso ao menor inteiro assinado representável:
1 <-- transportar bits 1000...00000 (-2^{N-1}) + 1111...11111 (-1)——————————————— 1|0111 ...11111 (2^{N-1} - 1)
Observe que o resultado carrega um bit adicional, produzindo um resultado que temN+1pedaços. Mas nosso sistema só suportaNbits, de modo que o líder1é realmente descartado. O resultado é o maior representávelN-bit inteiro assinado, e isso é conhecido comoestouro negativo de número inteiro.
Overflow e underflow são coisas que você deve estar atento em programas que realizam muitos cálculos, pois você pode acabar obtendo resultados inesperados.
O sistema numérico binário: tópicos adicionais para exploração
Isso é o suficiente para esta introdução ao sistema numérico binário! Analisamos profundamente o sistema decimal, binário e hexadecimal e espero que agora você aprecie melhor o sistema numérico binário e o papel que ele desempenha na computação.
Na realidade, há muito mais para aprender além do que abordamos aqui. Se você estiver curioso, encorajo você a pesquisarrepresentando números de ponto flutuante em bináriousando o formato IEE754.
Comentários
Comente no GitHub
Sistema de comentários desenvolvido pela API GitHub Issues. Você pode aprender mais sobrecomo eu construíou poste um comentário no GitHub, e ele aparecerá abaixo assim que você recarregar esta página.
Carregando...