Poesía Binaria

Bailando con bits: Trabajando a nivel de bit II

Hace unos días empecé con la serie Bailando con Bits (aunque llevaba escrito varios meses) trata de formas para trabajar a nivel de bit desde C.

Hoy voy a proponer otra forma, quizás menos intuitiva que la anterior, pero diferente. Esta vez no utilizaremos un registro enorme ni nada parecido, utilizaremos un mismo número entero para hacer el ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>

#define PESOBIT(bpos) 1<<bpos
#define COGEBIT(var,bpos) (var & PESOBIT(bpos))?1:0
#define PONE_1(var,bpos) var | PESOBIT(bpos)
#define PONE_0(var,bpos) var & ~(PESOBIT(bpos))
#define CAMBIA(var,bpos) var ^ PESOBIT(bpos)

int main()
{
  int numero;
  int i;

  numero=63;
  printf ("Numero: %d\n", numero);


  for (i=31; i>=0; i--)
    printf("%4d", i);

  printf("\n");

  for (i=31; i>=0; i--)
    printf("%4d",COGEBIT(numero,i));

  printf("\n");

  numero=PONE_1(numero, 17);
  numero=PONE_0(numero, 3);
  numero=CAMBIA(numero, 20);
  numero=CAMBIA(numero, 5);

  for (i=31; i>=0; i--)
    printf("%4d",COGEBIT(numero,i));

  printf("\nNúmero: %d\n", numero);

}

Ahora usamos varias macros que harán operaciones de bit con la variable a analizar (están definidas en la parte de arriba), tenemos PESOBIT, COGEBIT, PONE_1, PONE_0 y CAMBIA:

Como vemos en el ejemplo si queremos poner a 1 el bit 5 de numero, tendremos que hacer numero=PONE_1(numero,5), aunque en el siguiente ejemplo veremos cómo simplificar todo eso.

Con este ejemplo podemos jugar con los bits de números enteros. Pero, y si queremos utilizar otro tipo de variables? (aunque estamos limitados a 32bits) También tenemos este ejemplo con un tipo float:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>

#define PESOBIT(bpos) 1<<bpos
#define COGEBIT(var,bpos) (*(unsigned*)&var & PESOBIT(bpos))?1:0
#define PONE_1(var,bpos) *(unsigned*)&var |= PESOBIT(bpos)
#define PONE_0(var,bpos) *(unsigned*)&var &= ~(PESOBIT(bpos))
#define CAMBIA(var,bpos) *(unsigned*)&var ^= PESOBIT(bpos)

int main()
{
  float numero;

  int i;

  numero=63.2317;
  printf ("Numero: %f\n", numero);


  for (i=31; i>=0; i--)
    printf("%4d", i);

  printf("\n");

  for (i=31; i>=0; i--)
    printf("%4d",COGEBIT(numero,i));

  printf("\n");

  PONE_1(numero, 5);
  PONE_0(numero, 3);
  CAMBIA(numero, 20);
  CAMBIA(numero, 5);
  CAMBIA(numero, 31);

  for (i=31; i>=0; i--)
    printf("%4d",COGEBIT(numero,i));

  printf("\n");

  printf("\nNúmero: %f\n", numero);

}

En este caso no tenemos que hacer una variable igual a PONE_1(variable, 5) para poner su bit a 1; simplemente con PONE_1(variable, 5) nos vale. En este ejemplo podemos ver una variable de tipo float desglosada en bits y podemos modificar a nivel de bit para obtener otros valores. (No le veo mucha utilidad a esto, pero bueno).

Post dedicado a algm, por su comentario en el artículo Bailando con bits anterior.

Actualización Marzo 2016: foto principal

También podría interesarte....