Bitwise

Estructura de archivos:

📁 05_Bitwise
└── 📁 Bitwise-NN
    ├── 📄 main.c
    └── 📄 Makefile

Ejercicios:

Bitwise 01

Makefile


CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -pedantic

PROG = main
OBJ = main.o

$(PROG): $(OBJ)
	$(CC) $(OBJ) -o $(PROG)

$(OBJ): main.c
	$(CC) $(CFLAGS) -c main.c

.PHONY: clean
clean:
	del $(OBJ) $(PROG).exe

Código:


// gcc -std=c11 -Wall -Wextra -pedantic main.c -o main

#include <stdio.h>

int main(void)
{
    /* Declaracion de variables de tipo char (8 bits) */
    char A, B, C, D, E, F;

    /* Asignacion de valores hexadecimales:
     * 0xAC = 1010 1100
     * 0x69 = 0110 1001
     */
    A = 0xAC;
    B = 0x69;

    /* OR bit a bit (|)
     * A | B = C
     * 1 | 0 = 1
     * 0 | 1 = 1
     * 1 | 1 = 1
     * 0 | 0 = 0
     *
     *   1010 1100
     * | 0110 1001
     * -----------
     * 1110 1101 = 0xED
     */
    C = A | B;

    /* AND bit a bit (&)
     * A | B = C
     * 1 | 0 = 0
     * 0 | 1 = 0
     * 1 | 1 = 1
     * 0 | 0 = 0
     *
     * 1 & 1 = 1
     * Cualquier otro caso = 0
     *
     *   1010 1100
     * & 0110 1001
     * -----------
     *   0010 1000 = 0x28
     */
    D = A & B;

    /* XOR bit a bit (^)
     * A | B = C
     * 1 | 0 = 1
     * 0 | 1 = 1
     * 1 | 1 = 0
     * 0 | 0 = 0
     *
     *   1010 1100
     * ^ 0110 1001
     * -----------
     *   1100 0101 = 0xC5
     */
    E = A ^ B;

    /* Not (~) Invierte todos los bits:
     * A | F(~A)
     * 1 | 0
     * 0 | 1
     * 1 | 0
     * 0 | 1
     * 
     * A  = 1010 1100
     * ~A = 0101 0011 = 0x53
     */
    F = ~A;

    /* En esta linea se pisa el valor anterior de F.
     * A & 0x40
     * 0x40 = 0100 0000
     *
     * Esto es una MASCARA para aislar el bit 6 (contando desde 0: bit 0 es el menos significativo).
     *
     *   1010 1100
     * & 0100 0000
     * -----------
     *   0000 0000 => En este caso da 0
     *
     * Sirve para verificar si ese bit esta en 1.
     */
    F = A & 0x40;

    /* Lo mismo pero aplicado a B:
     *
     *   0110 1001
     * & 0100 0000
     * -----------
     *   0100 0000 => distinto de 0
     * Entonces el bit 6 de B esta en 1.
     */
    E = B & 0x40;
    
    return 0;
}

Bitwise 02

Makefile


CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -pedantic

PROG = main
OBJ = main.o

$(PROG): $(OBJ)
	$(CC) $(OBJ) -o $(PROG)

$(OBJ): main.c
	$(CC) $(CFLAGS) -c main.c

.PHONY: clean
clean:
	del $(OBJ) $(PROG).exe

Código:


// gcc -std=c11 -Wall -Wextra -pedantic main.c -o main

#include <stdio.h>
#include <conio.h> /* Se usa getche(); */
/* Se agrega stdlib.h por que usa system("cls");*/
#include <stdlib.h>

int main(void)
{
    int i, j;

    system("CLS");

    do
    {
        printf("\n\n\t\tIngrese un numero entero:");
        scanf("%d", &i);

        /* El especificador %04X:
         * 0 => Completa con ceros a la izquierda
         * 4 => Minimo 4 digitos
         * X => Imprime en hexadecimal mayuscula
         */
        printf("\n\t\tEl numero en hexadecimal es: %04X", i);

        /* Complementa a dos manual:
         * ~i => invierte todos los bits (Complemento a uno)
         * +1 => suma 1 (Complemento a dos)
         *
         * Esto equivale matematicamente a:
         * j = -i;
         */
        j = ~i + 1;

        /* Muestra el complemento a dos */
        printf("\n\n\t\tEl numero en complementos a dos es: %d", j);

        /* Muestra en formato hexadecimal mayuscula, minimo 4 digitos*/
        printf("\n\n\t\t En formato hexadecimal es %04X", j);

        /* Mostrar mensaje para usuario */
        printf("\n\n\nDesea continuar (S/N)? ");
    }
    while(getche() != 'N'); /* Sale si se presiona N */
    
    return 0;
}

Bitwise 03

Makefile


CC = gcc
CFLAGS = -std=c11 -Wall -Wextra -pedantic

PROG = main
OBJ = main.o

$(PROG): $(OBJ)
	$(CC) $(OBJ) -o $(PROG)

$(OBJ): main.c
	$(CC) $(CFLAGS) -c main.c

.PHONY: clean
clean:
	del $(OBJ) $(PROG).exe

Código:


// gcc -std=c11 -Wall -Wextra -pedantic main.c -o main

#include <stdio.h>
#include <conio.h> /* Se usa getch(), getche() */
/* Se agrega stdlib.h por que usa system("cls");*/
#include <stdlib.h>

/* Prototipos de funciones */
void conv(unsigned char, char, unsigned char, unsigned char);
void conv1(char, unsigned char, unsigned char);
void conv2(unsigned char, char, unsigned char, unsigned char);
void pasbin(unsigned char);

int main(void)
{
    /* Variables de 8 bits sin signo */
    unsigned char a, b, c;

    /* Variable auxiliar para ingreso y contadores */
    int i;
    do
    {
        /* Ingreso del primer numero */
        printf("\n\n\t\tIngrese un numero entero: ");
        scanf("%d", &i);

        /* Se guarda en variable de 8 bits (puede truncar) */
        a = i;

        /* Ingreso del segundo numero */
        printf("\n\t\tIngrese otro numero entero: ");
        scanf("%d", &i);

        /* Se guarda en variable de 8 bits (puede truncar) */
        b = i;

        /* Operador OR bit a bit y llamado a la funcion conv */
        printf("\n\n\t\t%d | %d = %d", a, b, a | b);
        conv(a, '|', b, a|b);

        /* Operador AND bit a bit y llamado a la funcion conv */
        printf("\n\n\t\t%d & %d = %d", a, b, a & b);
        conv(a, '&', b, a&b);

        /* Operador XOR bit a bit y llamado a la funcion conv */
        printf("\n\n\t\t%d ^ %d = %d", a, b, a ^ b);
        conv(a, '^', b, a^b);

        /* Operador NOT (complemento a uno) y llamado a la funcion conv1 para los numeros a y b */
        printf("\n\n\t\t~%d = %d", a, ~a);
        conv1('~', a, ~a);

        printf("\n\n\t\t~%d = %d", b, ~b);
        conv1('~', b, ~b);

        /* Pedido al usuario */
        printf("\n\n\t\t\tPresione una tecla para continuar");
        getch();

        /* Limpiar pantalla en Windows */
        system("CLS");

        printf("\n\n");

        /* Desplazamiento a la derecha y llamado a la funcion conv2 para a y b*/
        for (i = 0; i < 9; i++)
        {
            c = a >> i;

            printf("\n\t\t%d >> %d = %d", a, i, c);
            conv2(a, '>', i, c);
        }

        printf("\n\n");

        for (i = 0; i < 9; i++)
        {
            c = b >> i;

            printf("\n\t\t%d >> %d = %d ", b, i, c);
            conv2(b, '>', i, c);
        }

        printf("\n\n\t\t\tPresione una tecla para continuar");
        getch();

        system("CLS");

        printf("\n\n");

        /* Desplazamiento a izquierda y llamada a la funcion conv2 para a y b */
        for (i = 0; i < 9; i++)
        {
            c = a << i;

            printf("\n\t\t%d << %d = %d", a, i, c);
            conv2(a, '<', i, c);
        }

        printf("\n\n");

        for (i = 0; i < 9; i++)
        {
            c = b << i;

            printf("\n\t\t%d << %d = %d ", b, i, c);
            conv2(b, '<', i, c);
        }

        printf("\n\nDesea continuar (S/N)? ");
    }
    while(getche() != 'N'); /* Repite hasta presionar N */

    printf("\n\n");

    return 0;
}

/*
 * Muestra un numero de 8 bits en formato binario.
 * Recorre desde el bit mas significativo (0x80)
 * hasta el menos significativo (0x01).
*/
void pasbin(unsigned char nro)
{
    unsigned char aux;

    for (aux = 0x80; aux > 0; aux >>= 1)
    {
        if (nro & aux)
            printf("1");
        else
            printf("0");
    }
}

/*
 * Muestra la operacion binaria completa:
 * Ej.:
 *     10101010 | 01010101 = 11111111
 */
void conv(unsigned char a, char b, unsigned char c, unsigned char d)
{
    printf("\t\t");
    
    pasbin(a);
    
    printf(" %c ", b);

    pasbin(c);

    printf(" = ");

    pasbin(d);
}

/*
 * Muestra operacion NOT en formato binario.
 */
void conv1(char a, unsigned char b, unsigned char c)
{
    printf("\t\t%c", a);

    pasbin(b);

    printf(" = ");

    pasbin(c);
}

/*
 * Muestra desplazamientos << o >> en formato binario.
 */
void conv2(unsigned char a, char b, unsigned char c, unsigned char d)
{
    printf("\t\t");

    pasbin(a);

    printf(" %c%c %d = ", b, b, c);

    pasbin(d);
}