PCLP Laborator12: Optimizarea programelor folosind operaţii pe biţi

Obiective

În acest laborator vom studia:

Materiale utile

Exerciții

Discutați cu asistentul și scrieți pe tablă rezolvarea pentru exercițiile:

Veți rezolva individual:

ATENȚIE! Toate sarcinile se vor realiza folosind o abordare modularizată. Discutați cu asistentul alegerile voastre.

ATENȚIE! Se urmărește folosirea corespunzătoare a noțiunilor legate de operații pe biți.

BONUS-urile se rezolvă în următoarea ordine:


0: Verificare că un număr e par

Să se verifice folosind operații pe biți că un număr natural n e par.

int is_even(int n);

1. Calcul putere a lui 2

Să se scrie o funcție care să calculeze (2^n), unde ( n <= 30 ).

int pow2(int n);

Întrebări:

2. Negarea biților unui număr n

Să se scrie o funcție care să nege biții unui număr n (32 biți).

int flip_bits(int n);

Răspundeți la întrebarea: are sens să scriem o astfel de funcție?

3. Afișarea biților unui număr n

Să se scrie o funcție care să afișeze toți biții unui număr întreg pe 32 biți.

void print_bits(int n);

4. Verificare că un număr este putere al lui 2

Să se scrie o funcție care verifică dacă un număr întreg n pe 32 biți este puterea a lui 2. Funcția va returna 1 dacă n este putere a lui 2, 0 altfel.

int is_power2(int n);
Hint

Analizați reprezentarea în baza 2 a lui n (ex. n = 16 si n = 5).


5. bitset

O mulțime de numere întregi poate fi reprezentată astfel: spunem că un număr i aparține unei mulțimi S dacă bit-ul al i-lea din vectorul S are valoarea 1.

Pentru eficientă, vectorul S va conține date de tipul unsigned char (reamintim ca sizeof(unsigned char) == 1 byte adică 8 biți).

Notă:
Pentru a folosi cu ușurință același cod facând schimbări minime (de exemplu schimbăm dimensiunea maximă a unei mulțimi), putem să ne definim propriul tip astfel:

#define SET_SIZE 100                   // dimensiunea maximă alocată în bytes pentru o structură set
typedef unsigned char SET[SET_SIZE];   // definire tipul SET, care este un vector cu maxim 100 de elemente de tip unsigned char

5.1

Implementați următoarele funcții. Realizați un program în C prin care să demonstrați că funcțiile implementate funcționează.

Notă:
Există un exemplu detaliat care vă explică cum functionează aceastea.
Treceți la subpunctul următor abia după ce v-ați asigurat că acestea funcționează.

Urmăriți acest exemplu cu bitset pentru a înțelege cum funcționează aceste operații.

5.2

Realizați un program care, utilizând metodele definite anterior, citește 2 mulțimi A (n și B și afișează: ( A U B, A ∩ B, A - B, B - A ).

Pentru a realiza acest lucru, va trebui să implementați următoarele funcții:

În final va trebui sa creați o funcție main și să faceți un program care rezolvă cerința folosind funcțiile implementate.


B1. Optimizations

O să învățați pe viitor că nu toate înstrucțiunile sunt la fel din punct de vedere al timpului de execuției. Ca un punct de start, gândiți-vă că dacă ați face pe foaie o adunare sau o înmultire, durează mai mult să înmulțiți decât să adunați. Această dificulate o are și procesorul din laptopul vostru!

Pentru a-l ajuta și a face programul mai rapid, putem înlocui operații costisitoare (*, /) cu altele mai puțin costistoare (+, -). Cele mai rapide instrucțiuni sunt cele care lucrează direct pe biți (deoarece numerele sunt stocate în memorie în binar, deci este modul natural de lucru pentru calculator).

Acest exercițiu vă propune să aplicați aceste optimizări pe codul vostru!

Hint

Pentru a completa acest bonus, NU aveți voie să folosiți operatorii /, *, %! Încercați să folosiți operații pe biți!

B2. MSB/LSB

Să se scrie o câte o funcție pentru aflarea MSB (Most significant bit), respectiv LSB (Least significant bit), pentru un număr n pe 32 biți.

// returnează 2 la puterea i, unde i este LSB
int get_lsb(int n);
// returnează 2 la puterea i, unde i este MSB
int get_msb(int n);
Hint

Analizați reprezentarea în baza 2 a lui n.

Exemplu:

  • n = 20 are reprezentarea 0b10100 -> LSB = 2 (indicele 2), MSB = 4 (indicele 4).
  • get_lsb(20) va returna 4 (2 la puterea 2).
  • get_msb(20) va returna 16 (2 la puterea 4).

Problemset (extra)

Vă propunem să lucrați acasă probleme din PCLP Laborator12: Problemset (extra).