INF1018 - Software Básico

Operações bit a bit

  1. Considere uma variavel C, de nome x, do tipo unsigned int. Escreva expressões que, utilizando operações de manipulação de bits, obtenham os seguintes valores:

    • um valor de 32 bits com o byte menos significativo igual ao byte correspondente de x e todos os outros bits iguais a 0;
    • um valor de 32 bits com o byte menos significativo com todos os bits iguais a '1' e os outros bytes com o mesmo valor dos bytes correspondentes de x.

    Como exemplo, se o valor de x for 0x87654321, o resultado da avaliação da primeira expressão deverá ser 0x00000021 e o da segunda deverá ser 0x876543FF.

    Complete o programa abaixo com as suas expressões, compile-o e o execute para verificar se elas estão corretas:

    #include <stdio.h>
    int main(void) {
      unsigned int x = 0x87654321;
      unsigned int y, z;
    
      /* o byte menos significativo de x e os outros bits em 0 */
      y = ...;
    
      /* o byte menos significativo com todos os bits em '1' 
         e os outros bytes com o mesmo valor dos bytes de x */
      z = ...;
    
      printf("%08x %08x\n", y, z);
    }
    
    

  2. Escreva uma função que verifique se o número de bits '1' de um inteiro sem sinal é ímpar:

    int odd_ones(unsigned int x);
    
    Sua função deve retornar 0 se o número de bits '1' for par, e um valor diferente de 0 se o número de bits '1' for ímpar.

    Atenção: sua função NÃO PODE usar o operador % !

    Escreva uma função main e teste sua função odd_ones com diferentes valores de entrada, não esquecendo de verificar se os resultados obtidos estão corretos! Por exemplo, teste os valores 0x01010101 (número par de bits 1) e 0x01030101 (número ímpar de bits 1)


  3. Algoritmos de criptografia usam ticamente diversas operações de manipulação de bits. Algumas dessas operações não são oferecidas diretamente por C, mas podem ser implementadas a partir de suas operações básicas (and, or, shift).

    1. Implemente em C a operação switch_byte, que troca as duas "metades" de um byte. Por exemplo, se sua função receber como parâmetro o valor 0xAB ela deverá retornar 0xBA. O protótipo de sua função deverá ser
      unsigned char switch_byte(unsigned char x);
      

      Escreva uma função main e teste sua função switch_byte.

    2. Implemente agora a operação rotate_left (também chamada de "circular left shift").
      unsigned char rotate_left(unsigned char x, int n);
      
      Assim como um "left shift" (<<), ela desloca seu operando "n" bits para a esquerda. Porém, ao invés de preencher as posições livres à direita com zeros, ela as preenche com os "n" bits removidos pelo deslocamento.

      Considere, por exemplo, o valor 0x61 (0110 0001).

      • um "rotate left" de 1 bit resulta no valor 0xc2 (1100 0010)
      • um "rotate left" de 2 bits resulta no valor 0x85 (1000 0101)
      • um "rotate left" de 7 bits resulta no valor 0xb0 (1011 0000)

      Incorpore à sua função main testes para a função rotate_left, experimentando alguns valores diferentes para o deslocamento.

      Obs: você pode assumir que o valor do deslocamento será sempre um valor inteiro maior que 0 e menor que 8.