Binário para iniciantes: o ABC dos 0 e 1 | Aleksandr Hovhannisyan (2024)

O que é101010? 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?

101010tipos 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ígitos090–909para representar números simbolicamente, com base em sua posição em uma string.

Por exemplo, no sistema numérico decimal,579579579se expande para isso:

579=5(102)+7(101)+9(100)=500+70+9579 = 5(10^2) + 7(10^1) + 9(10^0) = 500 + 70 + 9579=5(102)+7(101)+9(100)=500+70+9

Na escola, você aprendeu que o555em579579579está na centésima casa, o777está na casa das dezenas e o999está no lugar das unidades. Observe que o555é multiplicado por cem (10210^2102), o777às dez (10110^1101), e a999por um (10010 ^ 0100) para formar o número decimal579579579. Dizemos que o número579579579é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úmero101010é o que chamamos debase(também conhecido comoraiz) do nosso sistema numérico. Observe os poderes de101010na expressão expandida acima:10210^2102,10110^1101, e10010 ^ 0100. 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 com10010 ^ 0100no “balde” mais à direita, seguido por10110^1101imediatamente à sua esquerda e assim por diante infinitamente:

Quaisquer buckets não utilizados na extrema esquerda têm um valor implícito de000neles. Geralmente cortamos os zeros à esquerda porque não adianta dizer005790057900579quando isso é matematicamente idêntico a579579579.

Por que os humanos escolheram101010ser 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 (base101010) 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 debbb, os dígitos disponíveis variam de000parab-1b-1b-1. Por exemplo, no sistema numérico decimal (b=10b = 10b=10), só podemos usar os dígitos0,1,2,...,90, 1, 2, ..., 90,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 depois999999, você carrega um para o balde representando a próxima potência de dez (100100100).

Agora, suponha que temos uma sequência de dígitosdn-1dn-2...d0d_{n-1} d_{n-2} ...d_0dn-1dn-2...d0(ondennné o número de dígitos). Talvez seja issod2d1d0=579d_2 d_1 d_0 = 579d2d1d0=579do nosso exemplo anterior. Essa string se expande assim:

dn-1bn-1+dn-2bn-2+...+d0b0d_{n-1} b^{n-1} + d_{n-2} b^{n-2} + ... + d_{0} b^0dn-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)d_{n-1} b^{n-1} + d_{n-2} b^{n-2} + ... + d_{0} b^0 = 5(10^2) + 7(10 ^1) + 9(10^0)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 (101010), conforme ilustrado abaixo:

Agora, na realidade, você pode ter um sistema numérico que usa uma base de222,333,444,120120120, 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-onvezes (por exemplo,xxxxseria4).
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–9ea-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 (geralmente0bpara binário ou0x/#para hexadecimal). Então nós escreveríamos579579579como57910579_{10}57910, ou o número binário100110011001como100121001_210012(ou0b1001\texto{0b}10010b1001). Caso contrário, se apenas escrevêssemos o número100110011001sem fornecer qualquer contexto, ninguém saberia se está em binário, octal, decimal, hexadecimal e assim por diante, porque os dígitos000e111també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 de222, e assim só podemos trabalhar com dois algarismos para compor números:000e111. 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:202 ^ 020,212^121,222 ^ 222, 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=020_{10} = 0_2010=02. Expansão:0(20)0 (2 ^ 0)0(20)
  • Um:110=121_{10} = 1_2110=12. Expansão:1(20)1(2^0)1(20)
  • Dois:210=1022_{10} = 10_2210=102. Expansão:1(21)+0(20)1(2^1) + 0(2^0)1(21)+0(20)
  • Três:310=1123_{10} = 11_2310=112. Expansão:1(21)+1(20)1(2^1) + 1(2^0)1(21)+1(20)
  • Quatro:410=10024_{10} = 100_2410=1002. Expansão:1(22)+0(21)+0(20)1(2^2) + 0(2^1) + 0(2^0)1(22)+0(21)+0(20)
  • Cinco:510=10125_{10} = 101_2510=1012. Expansão:1(22)+0(21)+1(20)1(2^2) + 0(2^1) + 1(2^0)1(22)+0(21)+1(20)

Tendo aprendido o sistema numérico binário, agora você deve entender a piada anterior:

101010tipos 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=21010_2 = 1 × 2^1 = 2_{10}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:000significa “desligado” (oufalsoem sua forma booleana) e111significa “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,,,?, e9numericamente 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-90-90-9(10)
  • Letras latinas maiúsculas:A-ZA-ZA-Z(26)
  • Letras latinas minúsculas:a-za-za-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 oito000areia111é 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 com888bits (um byte)?

Bem, usando a regra do produto da combinatória, temos oito “baldes”, cada um com dois valores possíveis: ou um000ou um111. Assim, temos2×2×...×2=282 × 2 × ... × 2 = 2 ^ 82×2×...×2=28valores possíveis.

Em decimal, isso é28=2562 ^ 8 = 25628=256valores possíveis. Por comparação,27=1282 ^ 7 = 12827=128. E128128128passa a ser o número de caracteres que queremos representar.

Então… Isso é estranho e aparentemente um desperdício, certo? Por que usamos888bits (um byte) para representar um caractere quando poderíamos usar777bits e atender à contagem precisa de caracteres que precisamos?

Boa pergunta! Usamos bytes porquenão é possível dividir igualmente um grupo de777pedaços, dificultando certos cálculos de baixo nível se decidirmos usar777bits 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 oxxdFerramenta Unix:

xxd-b arquivo

O-bflag 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)=721001001000 = 1(2^6) + 1(2^3) = 72_{10}01001000=1(26)+1(23)=7210. De acordo com nossa tabela ASCII, isso corresponde aHHH.
  • 01100101=1(26)+1(25)+1(22)+1(20)=1011001100101 = 1(2^6) + 1(2^5) + 1(2^2) + 1(2^0) = 101_{10}01100101=1(26)+1(25)+1(22)+1(20)=10110, qual éeeeem 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=32102^5 = 32_{10}25=3210em ASCII (que é de fatoEspaçoconforme a tabela).

A propósito, o que há com os números no lado esquerdo da saída? O que0000000c0000000c0000000cmesmo 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 de161616, o que significa que seus dígitos variam de0150–15015.

Esta é a primeira vez que encontramos um sistema numérico cujos dígitos são compostos por mais de dois caracteres. Como podemos apertar101010,111111, ou151515em 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 se151515é um seguido por cinco ou um único dígito de151515naqueles lugares. Mas, na realidade, usar delimitadores não é prático.

Vamos dar um passo atrás e considerar um número hexadecimal simples:

0x420x420x42

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 de161616:

0x42=4(161)+2(160)=6410+210=66100x42 = 4(16^1) + 2(16^0) = 64_{10} + 2_{10} = 66_{10}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 hexadecimais101010,111111, e assim por diante? Aqui está um exemplo que é bastante confuso, a menos que introduzamos alguma notação alternativa:

0x150x150x15

Isso é um151515em um único slot ou em um111e um555em 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]290x8[15]290x8[15]29

A melhor solução que as pessoas encontraram foi mapear101510–151015para as letras inglesasafa-faf. 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:

0xf40xf40xf4

E aqui está sua expansão:

0xf4=15(161)+4(160)=24010+410=244100xf4 = 15(16^1) + 4(16^0) = 240_{10} + 4_{10} = 244_{10}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 usamosxxdem 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 como000000060000000600000006, o que significa que agora estamos olhando para os bytes 6 a 11 (BparaR). Finalmente, o último rótulo deve fazer sentido agora que você conhece o sistema numérico hexadecimal:cmapas para121212, 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:

011011100101011011100101011011100101

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, temos161616dígitos de000para151515. Na terra binária, quantos bits precisamos para representar esses161616valores?

A resposta é quatro porque24=162 ^ 4 = 1624=16. Com quatro “baldes”, podemos criar os números zero (000000000000), um (000100010001), dez (101010101010), até quinze (111111111111). 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ó substituir101510–151015coma-fa-fa-fe terminamos:0x6e50x6e50x6e5.

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 hexadecimal0xad0 limite0xad. 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 seu444representação de bits e, em seguida, junte cada grupo!

a16=1010=10102d16=1310=11012ad16=101011012a_{16} = 10_{10} = 1010_{2} \\d_{16} = 13_{10} = 1101_{2} \\ad_{16} = 10101101_{2}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 como000, então ele está efetivamente desligado. Caso contrário, sua intensidade é modulada entre000e255255255, 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][42][87][f5][42][87][f5]

Agora, interpretamos o equivalente decimal para cada parte:

  • Vermelho:4216=4(161)+2(160)=6642_{16} = 4(16^1) + 2(16^0) = 664216=4(161)+2(160)=66
  • Verde:8716=8(161)+7(160)=13587_{16} = 8(16^1) + 7(16^0) = 1358716=8(161)+7(160)=135
  • Azul:f516=15(161)+5(160)=245f5_{16} = 15(16^1) + 5(16^0) = 245f516=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]0x4287f5 = 0b[0100][0010][1000][0111][1111][0101]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]0b[01000010][10000111][11110101]0b[01000010][10000111][11110101]

Observe que cada corcomponenteocupa um byte (888bits) 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 (888pedaços). Então as cores com as quais estamos acostumados são realmente242424-bit cores.

Isso significa que há uma enorme224=16,777,2162^{24} = 16.777.216224=16,777,216possíveis cores exclusivas que você pode gerar usando hex/rgb! O242424O 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 de000parafff. Isso nos dá um total de16×16×...×16=166=16,777,21616 × 16 × ... × 16 = 16 ^ 6 = 16.777.21616×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,216256 × 256 × 256 = 16.777.216256×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 apenas888bits para trabalhar, você está limitado a apenas28=2562 ^ 8 = 25628=256cores!

Naturalmente, você deve estar se perguntando: como eles se separaram888bits uniformemente entre vermelho, verde e azul? Afinal,888nã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ões323232inteiros de bits que a maioria dos computadores suporta. Poderíamos muito bem olhar646464-bit ouNNNinteiros de bits, mas é bom ter uma base simples para uma discussão.

Se tiver-mos323232bits para mexer, isso significa que podemos representar um total de232=4,294,967,2962^{32} = 4.294.967.296232=4,294,967,296(4 bilhões) números. De forma mais geral, se você tiverNNNbits para trabalhar, você pode representar2N2^N2Nvalores. 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 um000quando nosso número é positivo e um111quando é 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 inicial111, 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úmero1002100_21002normalmente significa4104_{10}410se 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íder111na 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úmero221022_{10}2210, que é representado assim em binário não assinado:

10110210110_2101102

Como estamos analisando um binário assinado, precisamos preencher esse número com um valor extra000na frente (ou então um líder111implicaria que é negativo):

0101102010110_20101102

Ok, então isso é positivo221022_{10}2210. Como representamos-2210-22_{10}-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 umNNNstring binária de -bit, um líder111em complemento de dois representa-1-1-1multiplicado por sua potência correspondente de dois (2n-12^{n-1}2n-1). Um dígito de111em qualquer outro slot representa+1+1+1vezes a sua potência correspondente de dois.

Por exemplo, o número assinado11010211010_2110102tem esta expansão:

110102=-1(24)+1(23)+1(21)=-1610+810+210=-61011010_2 = -1(2^4) + 1(2^3) + 1(2^1) = -16_{10} + 8_{10} + 2_{10} = -6_{10}110102=-1(24)+1(23)+1(21)=-1610+810+210=-610

Nós simplesmente tratamos o líder111como 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:

  1. Vire todos os bits (000torna-se111e vice versa).
  2. Adicionar111para o resultado.

Por exemplo, vamos converter431043_{10}4310para-4310-43_{10}-4310em binário:

+43 em binário: 0101011Invertido: 1010100Adicione um: 1010101

Qual é esse número? Deveria ser-4310-43_{10}-4310, então vamos expandi-lo manualmente para verificar:

-1(26)+1(24)+1(22)+1(20)=-6410+1610+410+110=-43-1(2^6) + 1(2^4) + 1(2^2) + 1(2^0) = -64_{10} + 16_{10} + 4_{10} + 1_{10} = -43-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 considerar323232inteiros de -bit novamente. Considerando que antes tínhamos323232bits para trabalhar para a magnitude de um número sem sinal, agora temos apenas313131para 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 ter2322^{32}232números para2312^{31}231números positivos e negativos, que é precisamente metade do que começamos (2322=231\frac{2^{32}}{2} = 2^{31}2232=231).

De modo mais geral, se você tiver umNNN-bit string binária assinada, haverá2N2^N2Nvalores, divididos igualmente entre2n-12^{n-1}2n-1positivos e2n-12^{n-1}2n-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-12^{31} - 1231-1, qual é2,147,483,6472.147.483.6472,147,483,647. Em Java, esse número é armazenado emInteiro.MAX_VALUE, e em C++, éstd::numeric_limits::max().

Mais genericamente, para umNNNsistema de bits, o maior inteiro assinado é2n-1-12^{n-1}-12n-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 usam323232Números inteiros assinados de -bit para representar a moeda do jogo, a “pilha de dinheiro” máxima que você pode definir exatamente231-12^{31} - 1231-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 um111e defina todos os bits restantes como um000:

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íder111é um-1-1-1vezes2n-12^{n-1}2n-1, e um111em qualquer outra posição será tratado como+1+1+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 como000.

Responder:-231-2^{31}-231

Em Java, esse valor é armazenado emInteiro.MIN_VALUE. Em C++, está emstd::numeric_limits::min().

De modo mais geral, se tivermos umaNNNsistema de bits, o menor int assinado representável é-2n-1-2^{n-1}-2n-1.

Observe que a magnitude do menor sinal323232-bit inteiro é exatamente um maior que a magnitude do maior sinal323232nú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,131313não é um dígito na base101010), 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 adicionar242424e181818em decimal:

24+ 18———— 42

Primeiro adicionamos o444e888obter121212, que não é um dígito compatível com o sistema numérico decimal. Então representamos a parte que podemos (222) e leve o valor restante (dez) para a próxima coluna como um111(1×101=10101 × 10^1 = 10_{10}1×101=1010). Nessa coluna, temos110+210+110=4101_{10} + 2_{10} + 1_{10} = 4_{10}110+210+110=410:

1 <-- carregado 24 + 18———————— 42

Agora, vamos adicionar esses mesmos dois números (241024_{10}2410e181018_{10}1810) usando o sistema numérico binário:

11000+ 10010——————— 101010

Trabalhamos da direita para a esquerda:

  • Um lugar:0+0=00 + 0 = 00+0=0
  • Lugar dois:0+1=10 + 1 = 10+1=1
  • Lugar de quatro:0+0=00 + 0 = 00+0=0
  • Oitavo lugar:1+0=11 + 0 = 11+0=1
  • Dezesseis lugares:1+1=1021 + 1 = 10_21+1=102(dois)

Este último passo merece alguns esclarecimentos: quando tentamos somar os dois, obtemos12+12=1021_2 + 1_2 = 10_212+12=102(dois), então colocamos um000na coluna atual e transferir o111para 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)=11 (transportado) + 0 (implícito) = 11(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=42101(2^5) + 1(2^3) + 1(2^1) = 32 + 8 + 2 = 42_{10}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+141022_{10} + 14_{10}2210+1410, que sabemos ser361036_{10}3610:

10110+ 01110——————— 100100

Algo interessante acontece quando olhamos para o lugar dos dois (o212^121coluna): adicionamos121_212para121_212, nos dando dois (10210_2102), então colocamos um zero no212^121coluna e carregue a restante.

Agora temos três unidades no222 ^ 222coluna:12(caRReued)+12(ópeRand1)+12(ópeRand2)=1121_2(transportado) + 1_2(operando1) + 1_2(operando2) = 11_212(caRReued)+12(ópeRand1)+12(ópeRand2)=112(três). Então colocamos um no222 ^ 222coluna 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=36101(2^5) + 1(2^2) = 32_{10} + 4_{10} = 36_{10}1(25)+1(22)=3210+410=3610

Subtraindo Números Binários

Subtração é adição com operando negativo:a-b=a+(-b)uma - b = uma + (-b)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-261012_{10} - 26_{10}1210-2610? Em decimal, sabemos que isso é-1410-14_{10}-1410. Em binário, sabemos que121012_{10}1210é011000110001100. A respeito-2610-26_{10}-2610? Representaremos isso usando o complemento de dois.

Começamos representando primeiro261026_{10}2610em binário:

+2610=0110102+26_{10} = 011010_2+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-1(2^5) + 1(2^4) + 1(2^1) = -32_{10} + 16_{10} + 2_{10} = -14_{10}-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 o222por cada dígito do primeiro multiplicando e escreva o resultado abaixo da barra:

21x 12———— 42

Então passamos para o111em121212e repita o processo, mas adicionando um000na 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=01010121_{10} = 0101012110=010101e1210=0110012_{10} = 011001210=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 é111, 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)=252100011111100_2 = 1(2^7) + 1(2^6) + 1(2^5) + 1(2^4) + 1(2^3) + 1(2^2) = 252_{10}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 dividir12610126_{10}12610por121012_{10}1210usando divisão longa:

0 1 0 . 5 _______12 |1 2 6 - 1 2 ———— 0 6 - 0 —————— 6 0 - 6 0 ————— 0

Responder:10,510,510.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.101010.101010.1.

O que faz o111à 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-110^{-1}10-1,10-210^{-2}10-2, e assim por diante.

Como você deve ter adivinhado, no sistema numérico binário, estes são2-12^{-1}2-1,2-22^{-2}2-2, e assim por diante. Então.1.1.1acima realmente significa1(2-1)1(2^{-1})1(2-1), qual é12=0.510\frac{1}{2} = 0,5_{10}21=0.510em decimal. E, claro, a parte na frente da vírgula decimal é avaliada como101010_{10}1010.

Isso nos dá1010+0.510=10,510_{10} + 0,5_{10} = 10,51010+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ávelNNN-bit inteiro assinado?

Por exemplo, seN=32N = 32N=32, estamos realmente perguntando o que acontece se tentarmos adicionar um ao maior representável323232-bit assinado int.

Vamos tentar:

0111...11111 + 0000...00001—————————

Na coluna mais à direita, obteremos12+12=1021_2 + 1_2 = 10_212+12=102, então isso é um zero e um um. Mas, como resultado, todas as adições restantes serão12+121_2 + 1_212+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 determinadoNNNsistema de bits, o resultadotransbordaouenvolve.

E se tentarmos subtrair um do menor representávelNNN-bit inteiro assinado? Primeiro, representaremos-110-1_{10}-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+1N+1N+1pedaços. Mas nosso sistema só suportaNNNbits, de modo que o líder111é realmente descartado. O resultado é o maior representávelNNN-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...

    Binário para iniciantes: o ABC dos 0 e 1 | Aleksandr Hovhannisyan (2024)
    Top Articles
    Latest Posts
    Article information

    Author: Greg Kuvalis

    Last Updated:

    Views: 6134

    Rating: 4.4 / 5 (55 voted)

    Reviews: 94% of readers found this page helpful

    Author information

    Name: Greg Kuvalis

    Birthday: 1996-12-20

    Address: 53157 Trantow Inlet, Townemouth, FL 92564-0267

    Phone: +68218650356656

    Job: IT Representative

    Hobby: Knitting, Amateur radio, Skiing, Running, Mountain biking, Slacklining, Electronics

    Introduction: My name is Greg Kuvalis, I am a witty, spotless, beautiful, charming, delightful, thankful, beautiful person who loves writing and wants to share my knowledge and understanding with you.