Tem alguma parte que será explicado como construir uma função para representação de um decimal em binário? Preciso da parte com máscara, manipulação de bits e campos de bits.
Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!
Tem alguma parte que será explicado como construir uma função para representação de um decimal em binário? Preciso da parte com máscara, manipulação de bits e campos de bits.
Já consegui resolver o problema. Como sou bonzinho e não encontrei nada em português que explica isto de forma detalhada, vou deixar registrado aqui caso alguém se depare com este problema.
Tópico: Manipulação de bits, máscara de bits, bitwise, bitmask
O problema é converter um número decimal decimal para binário. Para isso é necessário criar uma função, que por convenção é chamada displayBits. Antes de entender esta função é pré requisito saber os operadores de manipulação de bits, são apenas 6:
(&) (and)
(|) (OR inclusivo)
(^) (OR exclusivo)
(~) (Complemento)
(>>) (Deslocamento para direita)
(<<) (Deslocamento para esquerda)
Além disso, é preciso saber como funciona o operador condicional ternário (Condição ? TRUE : FALSE). Veja o pseudocódigo abaixo:
if(Qualquer valor diferente de 0){
faça isso;
}else{
faça isso;
}
A função foi retirada do livro C como programar, sexta edição, versão em português
#include <stdio.h>
void displayBits( unsigned value ); /* protótipo */
int main( void )
{
unsigned x; /* variável para manter entrada do usuário */
printf( "Digite um inteiro sem sinal: " );
scanf( "%u", &x );
displayBits( x );
return 0; /* indica conclusão bem-sucedida */
} /* fim do main */
/* mostra bits de um valor inteiro sem sinal */
void displayBits( unsigned value )
{
unsigned c; /* contador */
/* declara displayMask e desloca 31 bits à esquerda */
unsigned displayMask = 1 << 31;
printf( "%10u = ", value );
/* percorre os bits */
for ( c = 1; c <= 32; c++ ) {
putchar( value & displayMask ? '1' : '0' );
value <<= 1; /* desloca valor à esquerda em 1 */
if ( c % 8 == 0 ) { /* gera espaço após 8 bits */
putchar( ' ' );
} /* fim do if */
} /* fim do for */
putchar( '\n' );
}
Suponhamos que o usuário digite o número 5. Em binário fica: 00000000 00000000 00000000 00000101
Esse número 5 será recebido como parâmetro na função display bits e será armazenado na variável value do tipo int unsigned.
Na sequência é criado um número int unsigned 1 com deslocamento de 31 casas para a esquerda, vamos ver como isso acontece na prática. O número 1 em binário, considerando que o int unsigned, ocupa neste computador um tamanho de 4 Bytes, ou seja 32 bits (1 Byte = 8 bits), então vamos representar o número 1 que está em decimal para binário da seguinte forma.
00000000 00000000 00000000 00000001
Depois deslocamos o bit da primeira posição 31 casas para a esquerda, ele vai ficar da seguinte forma:
10000000 00000000 00000000 00000000
Este número em decimal na minha máquina, corresponde a 2147483648, este valor em decimal não importa para a gente agora.
Depois entraremos em um loop de 32 casas, pois precisamos percorrer todos os bits do nosso value.
Agora estamos em putchar( value & displayMask ? '1' : '0' ); Veja que o operador binário & irá fazer a seguinte operação
10000000 00000000 00000000 00000000 displayMask
00000000 00000000 00000000 00000101 Valor 5
000000000000000000000000000000000
Perceba que o resultado deu 0, logo o putchar() irá imprimir 0. O que temos no buffer de memória agora, quando c = 1, é apenas o caractere 0. Na sequência o valor 5 terá seu binário deslocado em uma posição através do deslocamento value <<= 1 (value = value << 1). Logo o número 5 se transformará em 10, pois em binário acontece um deslocamento de 1 casa, veja:
00000000 00000000 00000000 00000101 Valor 5
00000000 00000000 00000000 00001010 Valor 10
Agora, estamos na segunda volta do loop, para c = 2 e repetiremos a operação putchar( value & displayMask ? '1' : '0' );
10000000 00000000 00000000 00000000 displayMask
00000000 00000000 00000000 00001010 Valor 10
00000000 00000000 00000000 00000000 Valor 0
Agora na condição dentro de putchar( value & displayMask ? '1' : '0' ), putchar irá adicionar no buffer um novo 0, o buffer ficará assim: "00".
Vamos adiantar as coisas e avançarmos para o loop quando c vale 30. Neste cenário temos o seguinte
10000000 00000000 00000000 00000000 displayMask
10100000 00000000 00000000 00000000 Valor (x)
10100000 00000000 00000000 00000000 Valor != 0
Nesta altura do campeonato, o putchar() irá adicionar finalmente o número 1 e o buffer dele quando c = 30, será "00000000 00000000 00000000 000001"
No final do programa, quando c = 32, o buffer que putchar() terá será "00000000 00000000 00000000 00000101". Este valor em decimal é 5!