Nos artigos anteriores, exploramos
a aritmética dos computadores. Aprendemos como eles somam, subtraem usando
Complemento de Dois e como lidam com os limites físicos de memória (Overflow).
No artigo anterior, usamos brevemente o operador & para revelar a
representação interna dos números negativos em Python. Se você ficou curioso
sobre o que aquele & realmente fez — e o que mais é possível fazer com ele —,
chegou a hora de descobrir.
Nesses casos aritméticos, os bits eram tratados em conjunto para representar um valor numérico (peso posicional). Mas, às vezes, não queremos calcular o valor de um número. Queremos manipular a estrutura dele. Queremos acender uma “chave” específica, desligar um sensor, criptografar uma mensagem ou verificar permissões de um usuário.
É hora de deixar a aritmética de um pouco de lado e entrar no mundo da Lógica Bitwise (Bit a Bit). Aqui, o processador não enxerga o número “5” ou “10”, ele enxerga uma sequência de interruptores individuais que podem ser ligados (1) ou desligados (0).
A Conexão com a Lógica Proposicional #
Se você acompanha o blog, já deve ter lido nosso artigo sobre Lógica para Programadores. Lá, vimos como criar tabelas-verdade para decidir se uma proposição complexa é Verdadeira (V) ou Falsa (F).
A lógica bitwise é a aplicação direta desse conceito, mas em escala industrial:
- Verdadeiro (V) vira 1.
- Falso (F) vira 0.
Em vez de comparar apenas duas proposições (“A porta está aberta” E “A luz está acesa”), o operador bitwise compara 8, 16, 32 ou 64 pares de proposições de uma só vez, em paralelo.
O Grande Alerta: and não é &
#
Antes de vermos os operadores, precisamos resolver uma confusão clássica em
Python, linguagem mais adotada aqui no blog. Diferente de linguagens como C ou
Java, Python é muito verbal, usando palavras como and, or e not. Porém,
ele também possui os símbolos &, | e ~.
Eles não são a mesma coisa.
No artigo sobre Curto-Circuito em
Python,
explicamos que os operadores lógicos (and, or) são “preguiçosos”. Eles param
de avaliar assim que descobrem a resposta.
Já os operadores Bitwise (&, |) são “trabalhadores incansáveis”. Eles
avaliam todos os bits, sem exceção, e geram um novo número como resultado.
Tabela de Diferenças #
| Característica | Operadores Lógicos | Operadores Bitwise |
|---|---|---|
| Alvo | Expressões Booleanas (True/False) ou objetos | Números Inteiros (Bits individuais) |
| Avaliação | Curto-Circuito (Lazy evaluation) | Completa (Eager evaluation) |
| Resultado | Retorna um dos operandos (ex: True) |
Retorna um novo número inteiro |
| Exemplo | if idade > 18 and tem_cnh: |
masked = flags & 0xFF |
Jamais use & no lugar de and dentro de um if, a menos que você saiba exatamente o que está fazendo.
5 and 6retorna6(pois 5 é verdadeiro, ele segue e retorna o último).5 & 6retorna4(pois faz a interseção dos bits de 101 e 110).
São comportamentos completamente diferentes que podem gerar bugs silenciosos.
Agora que separamos a lógica de fluxo da lógica de bits, vamos conhecer as quatro ferramentas fundamentais: AND, OR, XOR e NOT.
A Matemática dos Bits: AND e OR #
Para entender bitwise, precisamos parar de olhar para o número decimal (ex: 12) e começar a olhar para a sua representação binária. As operações acontecem verticalmente, alinhando os bits correspondentes de cada número.
AND (&) - A Interseção
#
O operador E Bit a Bit (Bitwise AND) segue uma regra estrita: o bit de resultado será 1 se, e somente se, os bits de ambos os operandos forem 1.
Pense no AND como um Filtro ou uma Interseção.
1 & 1 = 11 & 0 = 00 & 1 = 00 & 0 = 0
Observe que o Zero é dominante: qualquer coisa combinada com zero vira zero. Essa propriedade torna o AND a ferramenta perfeita para desligar bits ou verificar valores (técnica conhecida como Masking).
Exemplo Prático: 12 & 10
Vamos operar 12 & 10.
- 12 em binário é
1100. - 10 em binário é
1010.
Alinhamos os bits e aplicamos a lógica coluna por coluna:
$$ \begin{array}{r c c c c l} & 1 & 1 & 0 & 0 & (12) \\ \& & 1 & 0 & 1 & 0 & (10) \\ \hline & 1 & 0 & 0 & 0 & (8) \end{array} $$Análise:
- Bit 3 (esquerda):
1 & 1resulta em 1. - Bit 2:
1 & 0resulta em 0. - Bit 1:
0 & 1resulta em 0. - Bit 0:
0 & 0resulta em 0.
Resultado: 1000 (que é 8 em decimal).
No Python:
print(12 & 10) # 8
print(bin(12 & 10)) # 0b1000OR (|) - A União
#
O operador OU Bit a Bit (Bitwise OR) é mais permissivo: o bit de resultado será 1 se pelo menos um dos bits dos operandos for 1.
Pense no OR como uma Soma Lógica ou União.
1 | 1 = 11 | 0 = 10 | 1 = 10 | 0 = 0
Aqui, o Um é dominante: qualquer coisa combinada com 1 vira 1. Essa propriedade torna o OR a ferramenta ideal para ligar bits (forçar um valor a 1) sem alterar os outros.
Exemplo Prático: 12 | 10
Vamos operar 12 | 10.
- 12 em binário é
1100. - 10 em binário é
1010.
Alinhamos os bits e aplicamos a lógica coluna por coluna:
$$ \begin{array}{r c c c c l} & 1 & 1 & 0 & 0 & (12) \\ \| & 1 & 0 & 1 & 0 & (10) \\ \hline & 1 & 1 & 1 & 0 & (14) \end{array} $$Análise:
- Onde havia pelo menos um bit
1nas entradas, a saída foi1. - Apenas a última coluna (
0 | 0) resultou em zero.
Resultado: 1110 (que é 14 em decimal).
No Python:
print(12 | 10) # 14
print(bin(12 | 10)) # 0b1110Resumo da Lógica #
Para não esquecer:
- AND (
&): Usado para Cortar/Limpar. Se você quer garantir que certos bits sejam zero, use AND com 0. - OR (
|): Usado para Adicionar/Ligar. Se você quer garantir que certos bits sejam um, use OR com 1.
Na próxima seção, veremos outros operadores: o XOR (o localizador de diferenças) e o NOT (a inversão total).
Os Operadores XOR e NOT #
Enquanto AND e OR são intuitivos (parecem interseção e união de conjuntos), os próximos dois operadores possuem comportamentos únicos que são a base da criptografia e da aritmética de inteiros.
XOR (^) - O Detetive de Diferenças
#
O OU Exclusivo (Exclusive OR, ou XOR) é um operador comum em
criptografia e algoritmos de hash. A regra é: o bit de resultado será 1 se os
bits dos operandos forem diferentes.
1 ^ 1 = 0(Iguais \(\to\) 0)0 ^ 0 = 0(Iguais \(\to\) 0)1 ^ 0 = 1(Diferentes \(\to\) 1)0 ^ 1 = 1(Diferentes \(\to\) 1)
Pense no XOR como um Alternador (Toggle).
- Se você faz XOR com
0, o bit original se mantém (1^0=1,0^0=0). - Se você faz XOR com
1, o bit original se inverte (1^1=0,0^1=1).
Sua utilidade em
criptografia
vem de uma propriedade bem mais forte do que “há tantos 0s quanto 1s no
resultado”: se o bit da chave for uniformemente aleatório, o bit de saída é
uniformemente aleatório, não importa qual fosse o bit da mensagem. Olhar para o
resultado não diz nada sobre o texto original — nem um pouquinho. Esse é o
argumento do one-time pad, o único esquema de cifra com sigilo perfeito
demonstrado, resultado provado por Claude Shannon em 1949.
Exemplo Prático: 12 ^ 10
Vamos operar 12 ^ 10.
Análise:
- Bit 3:
1e1são iguais \(\to\) 0. - Bit 2:
1e0são diferentes \(\to\) 1. - Bit 1:
0e1são diferentes \(\to\) 1. - Bit 0:
0e0são iguais \(\to\) 0.
Resultado: 0110 (que é 6 em decimal).
Curiosidade Criptográfica: O XOR é reversível. Se você calcular (A ^ B) ^ B, o resultado volta a ser A.
chave = 123
msg = 456
cripto = msg ^ chave
print(cripto) # 435
print(cripto ^ chave) # 456 — o XOR com a mesma chave desfaz a operaçãoO sigilo perfeito do parágrafo anterior vale sob duas condições rígidas: a chave precisa ser aleatória, tão longa quanto a mensagem, e nunca pode ser reutilizada. Um cifrador XOR com uma chave curta repetida ao longo do texto — que é o que quase todo mundo escreve na primeira tentativa — cai por análise de frequência, e sem precisar adivinhar a chave: posições separadas por um múltiplo do tamanho da chave foram cifradas com o mesmo byte, o que devolve o problema a uma cifra de substituição simples. Ótimo exercício de bits; péssima escolha para proteger qualquer coisa de verdade.
Essa reversibilidade rende um truque clássico: trocar o conteúdo de duas variáveis sem usar uma terceira.
a, b = 5, 9
a ^= b # a guarda agora a "diferença" entre os dois
b ^= a # b recebe o valor original de a
a ^= b # a recebe o valor original de b
print(a, b) # 9 5Funciona, mas vale mais como demonstração da propriedade do que como técnica. Em
Python, a, b = b, a é mais claro e mais rápido. E o truque esconde uma
armadilha: se os dois nomes apontarem para a mesma posição (lista[i] e
lista[j] com i == j), o primeiro XOR zera o valor e ele não volta nunca mais.
NOT (~) - A Inversão Total
#
O operador NÃO Bit a Bit (Bitwise NOT) é o único que opera sobre um único
número (operador unário). Ele simplesmente inverte todos os bits: o que é 0 vira 1, e
o que é 1 vira 0.
Visualmente, parece simples. Mas se você testar no Python, o resultado pode te confundir:
print(~0) # -1
print(~10) # -11Por que o resultado é negativo?
Aqui entra o conhecimento do nosso artigo anterior sobre Complemento de Dois.
- O Python trata inteiros como se tivessem “infinitos bits” à esquerda. O número
10positivo é...00001010. - Quando aplicamos o NOT (
~), invertemos todos os bits, inclusive os infinitos zeros à esquerda. O número vira...11110101. - Uma sequência infinita de
1s à esquerda indica um número negativo.
Matematicamente, em sistemas de Complemento de Dois, o operador ~x é equivalente ao Complemento de 1.
A relação com o valor decimal segue a fórmula:
Entendendo a Fórmula (~10)
Queremos calcular ~10.
- Pela fórmula matemática:
-(10) - 1 = -11. - Pela visão de bits (em 8 bits para simplificar):
-
10é0000 1010. -
Invertendo tudo (
~):1111 0101. -
O que é
1111 0101? Como o primeiro bit é 1, é negativo. -
Para descobrir o valor, aplicamos a regra inversa (Inverte e soma 1):
-
Inverte:
0000 1010(10) -
Soma 1:
0000 1011(11) -
Logo, o valor original era -11.
No próximo tópico, veremos como mover esses bits de um lado para o outro com os operadores de Shift (Deslocamento).
Shift: A Aritmética do Deslocamento #
Imagine que você tem o número decimal 23. Se você adicionar um zero à direita
(230), você efetivamente multiplicou o número por 10 (a base do sistema). Se
remover o último dígito (o 3), você dividiu por 10 (divisão inteira, restando 2).
No sistema binário, a lógica é idêntica, mas a base é 2. Mover os bits para a esquerda ou direita é a forma mais eficiente computacionalmente de multiplicar ou dividir números.
Left Shift (<<) - O Multiplicador
#
O operador Deslocamento à Esquerda (x << n) move todos os bits de x para
a esquerda por n posições.
- Os bits que “caem” pela esquerda são descartados (em tipos de tamanho fixo) ou o número cresce (em Python).
- Zeros são inseridos nas posições vagas à direita.
Regra Matemática:
Deslocar n bits para a esquerda equivale a multiplicar o número por \(2^n\).
Exemplo: 3 « 2
O número 3 em binário (8 bits) é 0000 0011.
Vamos deslocar 2 casas para a esquerda.
- Empurre tudo para a esquerda.
- Preencha os buracos da direita com
0. $$ \begin{array}{r c c l} & 0000 & 0011 & (3) \\ \downarrow & \text{Shift Left 2} & & \\ & 0000 & 11\mathbf{00} & (12) \end{array} $$ Verificação: \(3 \times 2^2 = 3 \times 4 = 12\).
Right Shift (>>) - O Divisor
#
O operador Deslocamento à Direita (x >> n) move os bits para a direita.
- Os bits da direita “caem” no abismo e são perdidos.
- O que entra pela esquerda? Aqui está o grande detalhe técnico.
Em linguagens de baixo nível, existem dois tipos de shift à direita:
- Logical Shift: Preenche sempre com 0. Usado para números sem sinal (Unsigned).
- Arithmetic Shift: Preenche com o valor do Bit de Sinal (o bit mais à esquerda). Se o número era negativo (começava com 1), ele preenche com 1s para manter o número negativo.
Como o Python faz?
Como Python lida com números com sinal e precisão arbitrária, o operador >> se comporta como um Arithmetic Shift. Ele preserva o sinal matemático.
Regra Matemática:
Deslocar n bits para a direita equivale a uma Divisão Inteira (Floor Division) por \(2^n\).
Com os dois operadores apresentados, vale ver os dois movimentos desenhados lado a lado. Repare no que entra e no que sai em cada caso — é essa assimetria que explica por que um deles é reversível e o outro não:

O << empurra zeros para dentro e, enquanto houver espaço, nada se perde. Já o
>> joga fora os bits da ponta direita, e esses bits eram justamente o resto da
divisão. É por isso que o deslocamento à direita equivale a uma divisão
inteira: o resto não vai para lugar nenhum, ele some.
Exemplo Positivo vs. Negativo
Caso 1: Positivo (12 » 2)
Binário: 0000 1100
Desloca direita, entra 0: 0000 0011
Resultado: 3. (Matemática: \(12 / 4 = 3\)).
Caso 2: Negativo (-12 » 2)
Binário (Complemento de 2): ...1111 0100
Desloca direita. Como o bit de sinal é 1, entram 1s pela esquerda.
Resultado: ...1111 1101
O resultado é -3. (Matemática: \(-12 / 4 = -3\)).
Isso garante que a divisão por potências de 2 funcione corretamente tanto para números positivos quanto negativos.
>> é piso, não truncamento
O exemplo acima passa a impressão de que >> e “dividir por 4” são a mesma
coisa, porque \(-12\) é múltiplo de 4 e o resultado sai redondo. Troque o
número por \(-13\) e a diferença aparece: -13 >> 2 devolve -4, enquanto
uma divisão que trunca em direção ao zero — como o / entre inteiros em C —
devolveria -3.
O motivo está na própria fórmula \(\lfloor x / 2^n \rfloor\): o piso arredonda
para baixo, e para números negativos “para baixo” é para longe do zero. Em
Python isso é coerente com o //, que também é piso (-13 // 4 é -4). Se
você precisa mesmo do truncamento, int(-13 / 4) devolve -3.
Na próxima seção, vamos juntar tudo o que aprendemos (AND, OR, NOT, SHIFT) para criar ferramentas práticas chamadas Máscaras de Bits (Bitmasks).
Máscaras de Bits (Bitmasks) #
Agora que conhecemos os operadores, podemos combiná-los para realizar alterações precisas em números. A técnica de usar um número auxiliar para “selecionar” ou “modificar” bits específicos de outro número é chamada de Mascaramento (Masking).
Para os exemplos abaixo, imagine que queremos manipular o 3º bit (da direita para esquerda, índice 2). Para isso, criamos uma máscara onde apenas esse bit é 1:
MASK = 1 << 2 # Resultado: 0b00000100 (Decimal 4)Consultar um Bit (Check) #
Queremos saber: “O 3º bit está ligado?”.
Usamos o AND (&). Como o AND com 0 zera tudo, se o resultado for diferente de zero, significa que o nosso bit alvo estava ligado.
flags = 0b10110111
is_on = (flags & MASK) != 0
# O resultado será True se o 3º bit estiver ligado (que é o caso), False caso contrário.Repare no != 0, e não > 0. Com os valores deste exemplo os dois funcionam,
mas o artigo anterior passou boa parte do tempo mostrando que inteiros podem ser
negativos — e, se flags for negativo (algo que o ~ produz com facilidade), o
resultado do & pode ser negativo também, e um teste > 0 responderia “bit
desligado” para um bit que está ligado. Comparar com zero por diferença é sempre
seguro.
Ligar um Bit (Set) #
Queremos forçar o 3º bit a ser 1, sem mexer nos outros.
Usamos o OR (|). Como o OR com 0 preserva o valor original, e o OR com 1 força virar 1, nossa máscara protege o resto e acende o alvo.
flags = flags | MASK
# Agora o 3º bit é 1 com certeza. Os outros não mudaram.Desligar um Bit (Clear) #
Queremos forçar o 3º bit a ser 0.
Esta é a operação mais complexa logicamente. Precisamos de um AND (para zerar), mas precisamos de uma máscara que tenha 0 no alvo e 1 em todo o resto (para preservar os vizinhos).
Como geramos isso? Invertendo nossa máscara original com NOT (~).
A Lógica do Clear (Limpar Bit)
- Máscara Original (
MASK):...0000 0100 - Máscara Invertida (
~MASK):...1111 1011 - Operação (
flags & ~MASK):...10110011
O bit alvo foi zerado, os outros foram preservados pelos 1s da máscara.
flags = flags & (~MASK)Alternar um Bit (Toggle) #
Queremos inverter o estado atual: se estava ligado, desliga; se estava desligado, liga.
Usamos o XOR (^), pois XOR com 1 sempre inverte o bit.
flags = flags ^ MASKAs quatro operações formam um conjunto fechado, e é útil vê-las juntas depois de tê-las visto uma a uma. A figura abaixo repete o mesmo bit alvo nos quatro casos, com a coluna dele destacada, para que dê para comparar o que cada operador faz com os vizinhos:

Repare no padrão: o bit alvo muda em todas, e as outras sete colunas ficam intactas em todas. É esse o ponto do mascaramento — mexer numa posição sem tocar em nenhuma outra.
Duas funções que poupam trabalho #
Python já traz embutidas duas operações que aparecem o tempo todo em código real de manipulação de bits e que evitam escrever laços na mão:
flags = 0b10110111
flags.bit_count() # 6 — quantos bits estão ligados (Python 3.10+)
flags.bit_length() # 8 — quantos bits são necessários para representar o valorbit_count() é o que a literatura chama de popcount, e responde em uma chamada
perguntas como “quantas permissões esse usuário tem?” ou “quantos itens estão
marcados?”. bit_length() responde “onde está o bit mais significativo ligado?”,
útil para saber quantos bits um valor realmente ocupa.
Se esse tipo de manipulação te interessou, a referência prática do assunto é o Bit Twiddling Hacks, de Sean Eron Anderson — uma coletânea de truques de bits para tarefas que, à primeira vista, pareceriam exigir laços e condicionais.
Exemplo Real: Sistema de Permissões #
Vamos ver onde isso é usado na prática. Sistemas operacionais (como Linux) usam bits para controlar permissões de arquivos. Vamos simular isso em Python.
Imagine que temos 3 permissões possíveis, representadas por bits:
- Leitura (READ): bit 2 (valor 4)
- Escrita (WRITE): bit 1 (valor 2)
- Execução (EXEC): bit 0 (valor 1)
# Definindo as constantes (MÁSCARAS)
READ = 0b100 # 4
WRITE = 0b010 # 2
EXEC = 0b001 # 1
# Cenário 1: Criando um usuário com permissão de Leitura e Execução
# Usamos OR (|) para combinar as permissões
permissao_usuario = READ | EXEC
print(bin(permissao_usuario)) # Saída: 0b101 (Decimal 5)
# Cenário 2: O usuário pode escrever?
# Usamos AND (&) para verificar
if (permissao_usuario & WRITE):
print("Acesso de escrita liberado")
else:
print("Acesso de escrita negado") # Vai cair aqui
# Cenário 3: Adicionando permissão de escrita dinamicamente
permissao_usuario = permissao_usuario | WRITE
print(bin(permissao_usuario))
# Agora o valor é 0b111 (7) - Permissão total (rwx)
# Cenário 4: Revogando permissão de execução
# Usamos AND com NOT
permissao_usuario = permissao_usuario & (~EXEC)
print(bin(permissao_usuario))
# Agora o valor é 0b110 (6) - Apenas Leitura e EscritaPerceba como conseguimos armazenar 3 informações booleanas independentes em uma única variável inteira, usando apenas 3 bits de informação.
Aqui vale uma precisão que costuma passar batida: nada disso ocupa “3 bits de
memória”. A menor unidade endereçável de memória é o byte, e um int do Python,
com toda a maquinaria de precisão arbitrária que carrega, ocupa 28 bytes —
sys.getsizeof(5) mostra isso. O que cabe em 3 bits é a informação. A
economia real aparece quando esses bits são empacotados aos milhões, em
protocolos de rede, formatos de arquivo e estruturas de dados compactas.
755 do chmod
Os três bits que acabamos de usar — leitura, escrita, execução — são exatamente
os do Unix, e agora dá para ver por que o comando de permissões aparece em
octal. As permissões de um arquivo são nove bits, em três grupos de três:
dono, grupo e outros. E três bits é precisamente o que um dígito octal
representa. Ou seja, chmod 755 é a escrita octal de 111 101 101:
| Grupo | Dígito octal | Bits | Significado |
|---|---|---|---|
| Dono | 7 | 111 |
ler, escrever, executar |
| Grupo | 5 | 101 |
ler e executar |
| Outros | 5 | 101 |
ler e executar |
É por isso que o primeiro artigo desta série dedicou uma seção inteira ao octal: ele não é curiosidade histórica, é a notação que torna nove bits de permissão legíveis de relance. Mais detalhes em file-system permissions.
Tabela-Resumo #
| Operação | O que faz | Exemplo do artigo |
|---|---|---|
& (AND) |
bit 1 só se ambos forem 1 | 12 & 10 = 8 |
| (OR) |
bit 1 se algum for 1 | 12 | 10 = 14 |
^ (XOR) |
bit 1 se forem diferentes | 12 ^ 10 = 6 |
~ (NOT) |
inverte todos os bits: \(\sim x = -x - 1\) | ~10 = -11 |
<< |
desloca à esquerda: multiplica por \(2^n\) | 3 << 2 = 12 |
>> |
desloca à direita: \(\lfloor x / 2^n \rfloor\) | -12 >> 2 = -3, mas -13 >> 2 = -4 |
and / or |
operam sobre valores de verdade, não sobre bits | 5 and 6 devolve 6, não 4 |
| Consultar bit | (flags & MASK) != 0 |
bit 2 de 0b10110111 está ligado |
| Ligar bit | flags | MASK |
preserva os vizinhos |
| Desligar bit | flags & ~MASK |
0b10110111 & ~0b100 = 0b10110011 |
| Alternar bit | flags ^ MASK |
XOR com 1 sempre inverte |
| Criar máscara | 1 << n |
1 << 2 é 0b100 |
| Contar bits ligados | x.bit_count() |
0b10110111 tem 6 |
| Tamanho em bits | x.bit_length() |
0b10110111 ocupa 8 |
| Reverter XOR | (A ^ B) ^ B == A |
base do cifrador e da troca sem variável extra |
Conclusão #
Entrar no mundo Bitwise é como olhar para a Matrix: você para de ver apenas os números superficiais e começa a enxergar a estrutura binária que sustenta tudo.
Embora Python seja uma linguagem de alto nível, entender &, |, ^ e << te
dá superpoderes para lidar com protocolos de rede, processamento de imagens,
criptografia e otimização de algoritmos.
E caso não use Python, esses conceitos são universais e se aplicam a praticamente todas as linguagens de programação.
Agora você sabe que:
- Bitwise não é Lógico:
&não éand. - Máscaras são a chave: Use
ANDpara ler/limpar eORpara escrever. - Bits são versáteis: Um único inteiro pode guardar dezenas de “interruptores” independentes.
Pronto para praticar? Tente criar um código que criptografa uma string usando XOR e depois descriptografa usando a mesma chave — lembrando do alerta lá de cima: isso é exercício de manipulação de bits, não proteção de verdade.
Com isso, encerramos o capítulo dos números inteiros nesta série. Ao longo
dos últimos artigos, vimos como representar, converter, operar e manipular
inteiros em diferentes bases — inclusive na estrutura de bits bruta. Agora é
hora de dar o próximo salto: como o computador lida com números
fracionários? Por que 0.1 + 0.2 não é exatamente 0.3 em Python? A
resposta começa com algo que você já domina — conversão de bases —, mas aplicada
agora à parte depois da vírgula.
Até a próxima!