Ir ao conteúdo
  • Cadastre-se
JACK_SNOWSTALKER

Escovando Bits em C

Recommended Posts

Oi gente, estou fazendo um trabalho, e estou fazendo uma versão primaria (para entrega) que tem um desempenho terrivel, eu comecei a ter algumas ideias para fazer versões otimizadas assim que garantir que essa versão primária funcione (não quero correr o risco de me envolver muito com otimização e perder prazo), mas tenho um problema técnico...como posso manipular os Bits? Eu preciso somar eles com carry, gostaria de separar em grupos de 4 bits para separar e imprimir na tela em digitos (como 4 bits vai de 0 a 15 sem sinal, quero usar 4 bits e quebrar para imprimir cada digito do valor inteiro na tela), alguem pode dar uma força? Eu quero imprimir binário na tela (converter em digitos de 0 a 9 e ir imprimindo) e manipular os bits fazendo operações...mas tenho problemas pra fazer isso em C e embora conheça maneiras de fazer isso em Assembly, considerando os tipos de estruturas que estou fazendo é uma má ideia trabalhar Assembly.

Compartilhar este post


Link para o post
Compartilhar em outros sites

http://en.wikipedia.org/wiki/Bitwise_operations_in_C

 

XOR --> ^

OR --> |

AND --> &

Shift left --> <<

Shift right --> >>

 

Quanto aos quatro bits, acho que o menor tamanho que o C padrão usa é um byte (char). Mas você pode usar máscaras neles pra separar os bits (0xF0 pros 4 primeiros e 0x0F pros 4 ultimos).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Você pode usar uma máscara,

Por exemplo, para tratar 1 byte.

    unsigned char x = 191, y = 1<<7;       // desloca à esquerda    x <<= 1;    if(x & y) puts("carry 1");    x <<= 1;    if(x & y) puts("carry 2");    x <<= 1;    if(x & y) puts("carry 3");

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ok!
Em C, existe um recurso de manipulação de baixo nível por struct.

Veja o simples exemplo abaixo de um struct de apenas 1 byte de tamanho:

struct byte_bit{    //Um byte    char bit_0: 1;//Mais baixo bit = 1    char bit_1: 1;    char bit_2: 1;    char bit_3: 1;    char bit_4: 1;    char bit_5: 1;    char bit_6: 1;    char bit_7: 1; //Mais alto bit = 128} stByte; //Tenho apenas 1 byte;

para acessar qualquer bit basta fazer:

stByte.bit_7 = 1; //Ativar bit

Compartilhar este post


Link para o post
Compartilhar em outros sites

Muito interessante usar máscaras, eu tinha visto que o menor tamanho do C é um byte, eu não sabia bem como tratar de 4 em 4, muito obrigado. Vou ter que tirar a ferrugem das aulas de Introdução a Sistemas Digitais! Eu achei muito interessante essa estrutura...já estou com duas, mais uma não seria problema, só que eu achei muito esquisito isso, ela tem 1 byte? mas tem 8 chars de 1 byte????? Buguei com isso, o compilador C compacta isso em um byte????

Compartilhar este post


Link para o post
Compartilhar em outros sites

Exato!
O C muito poderoso mesmo né. Por esse e por outros motivos que a maioria dos drives são escrito em C,

você manipula baixo nível de modo ultra acessível. 

 

Para confirma esse poder, faça um teste:

printf("Quantos bytes tem %u", sizeof (struct byte_bit) );

Quantos bytes tem 1

 

:)

Compartilhar este post


Link para o post
Compartilhar em outros sites

Campos de bits é um recurso interessante, mas acredito que esse método não é portável.

Você pode, por exemplo, empacotar bits onde a sequecia pode variar dependendo da arquitetura que estive rodando. Por exemplo big endian/little endian.

Sobre a quantidade de bits, isso depende do compilador.

  • Curtir 1

Compartilhar este post


Link para o post
Compartilhar em outros sites

Sim, porém o limite de manipulação de dados depende da estrutura do processador, no caso 1 byte e o mínimo.

independeste das circunstancia, limite imposto manipulação aos noobs, que é hack, faz manobras incríveis e burla isso no estralar.

 

Veja bem:

Por exemplo se eu adiciona se mais um Label;

char bit_8: 1; //Mais alto bit 

 

O tamanho da estrutura na memoria será 2 bytes, porém se restrugi a manipular apenas 9 bits, desperdiçando o resto.

Essa regra serve exatamente ao inverso limitando se sempre ao minimo de 1 byte. 

 

Caso não tenho notado 1 apos o Label determina o limite minimo de bits a ser manipulado por Label:

 

struct byte_bit
{
    //Um byte
    char bit_0: 2;//Mais baixo bit = 1
    char bit_1: 2;
    char bit_2: 2;
    char bit_3: 2; //Mais alto bit = 128

} stByte; //Tenho apenas 1 byte (8 bits);

 

Também se aplicando nas mais diversão variações que você imaginas, até mesmo para criar seu próprios tipos de dados,

C++ por exemplo usa esse conceito.

Não é querendo puxar o saco em dizer que C e melhor do C++, mas tudo que é escrito em C++, e transformado e C e por fim em bits.

EU AMO ♥ C;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu perguntei isso porque seria interessante pra mim trabalhar com 4bits por vez, porque eu preciso depois converter cada binario em um digito numérico em ASCII pra imprimir na tela, com 4 bits fica mais fácil definir cada digito. Já emendo essa, como pegar e converter cada trecho binário em digito? Eu ando pensando em gambiarras....não posso me atrelar a tipos, preciso pegar o binário e converter em ASCII, cada digito de 0 a 9.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se você quer apenas converter binário para decimal e vice versa (ou hex, etc), pode trabalhar perfeitamente com o tamanho nativo dos tipos disponibilizados pela linguagem/compilador.

Não vejo vantagem em querer criar dados menores.

Veja um exemplo, no código abaixo converto binário para decimal.

O tamanho máximo é de 8 bits, mas alterando o tamanho do vetor bits, o programa pode converter para valores maiores.

    char bits[9];    long i, decimal = 0, b = 1;    printf("bits: ");    scanf("%s", bits);    for(i = strlen(bits) - 1; i >= 0; i--){                decimal += b * (bits[i] - '0');               b *= 2;    }    printf("%s = %d\n", bits, decimal);

Compartilhar este post


Link para o post
Compartilhar em outros sites

a questão é que eu preciso trabalhar com tamanhos variados de Bits, e eles podem não ser suficientes nos padrões do C, então preciso trabalhar com estruturas (que eu criei) para trabalhar com dados maiores que os tipos que existem em C, mas o problema é imprimir isso na tela (em números decimais).

Compartilhar este post


Link para o post
Compartilhar em outros sites

Ok!

Observe que aliando a struct você vai utilizar outro poderoso recurso da linguagem;

union

Veja abaixo:

/* union.c -- soma dos n-elementos na mesma celula  */#include <stdio.h>#include <stdlib.h>/* minhas struct bit[4]*/struct myByte{    unsigned char bit_0_4: 4; //Mais baixo nível    unsigned char bit_5_7: 4; //Mais alto  nível}; //Tenho 8 bits;typedef union byte_bit //Poderoso recurso de edição de tipos{    struct myByte byte;    char unsigned interge;} Byte; //Novo tipo de dadosint main(void){    Byte b;    b.byte.bit_0_4 = 8; //Mais baixo nível **** 1000;    printf ("Meu tamanho e:   %u""\n", sizeof(struct myByte));    printf("Meu Integer e=:   %u""\n", b.interge);    printf("Meu numero char=: %c""\n", b.byte.bit_0_4 + '0');    return (0);} 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×