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.
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!