Dúvida sobre bytes em c/c++.

1. Dúvida sobre bytes em c/c++.

rob
robgeek

(usa Debian)

Enviado em 26/03/2017 - 11:01h

Olá!

Gostaria de saber se existe alguma forma de eu tratar dados de uma forma diferente da tradicional. Digamos, a unidade mais básica(exceto o bit) de dado é o byte. Em c/c++ os dados são tratados sempre como bytes ou múltiplos dele, quando você declara um int, char, e por aí vai.

Mas e se eu quisesse criar um programa que escreve em um arquivo e lê dele, mas sempre de 5 em 5 bits. Ou seja, cada dado agora é representado por 5 bits. Tem como fazer isso ou estou preso aos 8 bits tradicionais?

O que me confunde a cabeça é que neste exemplo, digamos que eu queira representar qualquer coisa no primeiro "byte"(que agora tem 5bits), ainda restarão 3 bits(considerando o byte tradicional) que seria parte de um segundo dado. Eu obteria os dois bits restantes no próximo byte tradicional. Como fazer esse tratamento é que me deixa confuso.

De preferência em c++.

Obrigado!


  


2. Re: Dúvida sobre bytes em c/c++.

Paulo
paulo1205

(usa Ubuntu)

Enviado em 26/03/2017 - 22:47h

Certamente dá para fazer, mas não diretamente com tipos nativos, pois, por definição, char é a menor unidade cujo endereço pode ser diretamente manipulado e também por definição, ela tem de ter tamanho mínimo de oito bits.

Contudo, você pode criar uma classe que faça o que você quer, implementando a lógica que você acha que deve existir para obter alocação para múltiplos objetos semelhantes de bytes de cinco bits, com um mínimo de desperdício de memória (sabedor, porém, que essa economia de memória pode acarretar custo de processamento).

Eu sei que é um pouco diferente do que você quer, já que trabalha com arrays, em lugar de objetos individuais, mas não deixa de ser um exemplo de como individualizar o acesso a um dado de tamanho menor que um byte: a biblioteca padrão do C++ tem a classe std::bitset, que permite endereçar criar arrays de bits, permitindo usar uma sintaxe semelhante à de array para endereçar bit-a-bit.


3. Re: Dúvida sobre bytes em c/c++.

Perfil removido
removido

(usa Nenhuma)

Enviado em 27/03/2017 - 06:08h

Dá para fazer mas para quem não consegue enxergar a coisa é enrolado.
Você precisa de um pedaço de papel e um lápis para modelar visualmente.

Como você lê os primeiros cinco bits de um tipo char?

dado_5_bits = variavel_lida & bit_mascara;

Onde o bit mascara terá o valor binário de 11111000.
Isto é 15x8 = 120.

Com o resto fica assim:

resto_3_bits = variavel_lida & outro_bit_mascara

Onde essa outra máscara terá o valor binário de 00000111, ou 7 em decimal.

É mais ou menos isto.

Precisa filtrar o dado de 5 bits, guardar o resto, criar um novo dado com o resto da variável ajuntado com o começo da próxima e ir interpretando.

Lembrando de que estas máscaras mudam de valor.
A primeira é 11111000 e 00000111.
A segunda é 11000000 e 00111111.
Etc.

Precisa ler e concatenar dados e ir rolando as máscaras em valor decimal.

----------------------------------------------------------------------------------------------------------------
Nem direita, nem esquerda. Quando se trata de corrupção o Brasil é ambidestro.
(anônimo)

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden



4. Re: Dúvida sobre bytes em c/c++.

Enzo de Brito Ferber
EnzoFerber

(usa FreeBSD)

Enviado em 28/03/2017 - 16:40h

Olá,

Como já dito, você não pode ler apenas 5 bits, e sim 8, o mínimo.

Por exemplo, se você tem um arquivo aberto FILE *fp, você pode ler com:


char byte;
fread(&byte, 1, sizeof byte, fp);


O que você pode fazer, na verdade, é ler um múltiplo de 5 bits que também é multiplo de 8 bits. No caso, 5 e 8 são primos entre si, portanto o MMC = 40.
Se você ler exatamente 40 bits do arquivo, você terá 8 unidades de 5 bits. Para ler 40 bits, você precisa de 5 bytes.

Portanto, algo como:

char byte[5];
fread(byte, 5, sizeof byte, fp);


E aí você trata cada unidade separadamente. Abaixo mostro um exemplo:


/* bit.c
* gcc -o bit bit.c -Wall
*
* (C) 2017 - Enzo Ferber, <enzoferber@gmail.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>


typedef unsigned char byte;

void print_bin(byte n)
{
byte i;

printf("%d: ", n);
for(i = 128; i > 0; i >>= 1)
printf("%c", !!(n & i) + '0');

putchar('\n');
}

int main(int argc, char *argv[])
{
int i;
byte data[5];
FILE *fp = fopen("file", "rb");
/* file e um arquivo texto com o conteudo:
*
* ABCDE
*
*/

fread(data, 5, sizeof(byte), fp);

/* mostra que tudo esta ok com a leitura */
for(i = 0; i < 5; i++)
print_bin(data[i]);

/* 5 bits no primeiro byte
*
* 1111 1000 = 0xf8
*/
byte un1 = (data[0] & 0xf8) >> 3;
print_bin(un1);

/* 3 bits no primeiro, 2 bits no segundo:
*
* byte1 byte2
* --------- ---------
* 0000 0111 1100 0000
*
* 0x07 0xc0
*/
byte un2 = ((data[0] & 0x07) << 2) | ((data[1] & 0xc0) >> 6);
print_bin(un2);

/* 5 bits no byte 2
*
* 0011 1110
*
* 0x3e
*/
byte un3 = ((data[1] & 0x3e) >> 1);
print_bin(un3);

/* 1 bit no segundo, 4 bits no terceiro
*
* byte 2 byte 3
* -------- ---------
* 0000 0001 1111 0000
*
* 0x01 0xf0
*/
byte un4 = ((data[1] & 0x01) << 4) | ((data[2] & 0xf0) >> 4);
print_bin(un4);

return 0;
}
/* EoF */


Arquivo 'file':

ABCDE


Fiz os 4 primeiros conjuntos de 5 bits pra você ver mais ou menos como fazer. Os próximos 4 conjuntos você vai precisar fazer. Dica: escreva uma tabela hexadecimal-binário em um papel, usando apenas 4 bits binários. Assim fica fácil converter binário para hexa de cabeça:

Exemplo: Converter 0011 1110 para hexa:

Se você tem a tabela, sabe que os 4 primeiros bits (0011) em hexa equivalem a 3. Os próximos 4 bits (1110) equivalem a 'e'. Portanto, 0011 1110 = 0x3e.

Qualquer coisa posta denovo,



Enzo Ferber
[]'s


$ indent -kr -i8 src.c

"(...)all right-thinking people know that (a) K&R are _right_ and (b) K&R are right."
- linux/Documentation/CodingStyle - TORVALDS, Linus.







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts