Programare: Tema 5

Problema 1 Scrieți o funcție care calculează produsul a două numere pe 16 biți folosind operatori pe biți și adunare.

Problema 2 Scrieți o funcție care calculează câtul și restul la împărțirea a doi întregi fără semn, calculând pe rând fiecare bit din rezultat (ca la împărțirea din școala primară)

Problema 3 Scrieți o funcție care ia ca parametri două numere întregi fără semn și returnează rezultatul împărțirii lor, ca float, calculând succesiv fiecare bit din mantisă.

Problema 4 Scrieți un program care calculează o sumă de control CRC (cyclic redundancy check) pentru un text, conform standardului POSIX.
Fundamentul matematic este următorul: textul e asimilat unui șir de L biți, pentru care se calculează o sumă de control pe W biți. Orice șir de n biți poate fi asociat cu un polinom de grad < n, în care bitul k este coeficientul lui x la puterea k. Se ia textul, privit ca un astfel de polinom, și se calculează restul împărțirii la un polinom prestabilit de grad W, considerând toți coeficienții modulo 2. De exemplu, pentru textul pe L=8 biti 10011100, adică x^7 + x^4 + x^3 + x^2 și polinomul x^4 + x^3 + x^0 (11001, de grad W=4) obținem:
x^7 + x^4 + x^3 + x^2 = (x^3 + x^2 + x^1)*(x^4 + x^3 + x^0) + x^1 (mod 2)
deci restul x^1 interpretat pe W=4 biți este 0010. Împărțirea poate fi implementată prin algoritmul clasic cu deplasare și scădere succesivă. Exprimând totul în calcule pe biți, avem nevoie de o valoare pe W biți în care ținem minte restul curent. Scăderea pentru polinoame modulo 2 (identică cu adunarea) se face prin SAU exclusiv bit cu bit (nu există deplasare, fiecare bit corespunde unui coeficient separat). Dacă bitul superior (poziția W-1) este 1, atunci în iterația curentă, după deplasarea la stânga și aducerea următoarei cifre din deîmpărțit, bitul W va fi 1 și împărțitorul (de grad W) va "intra" în rest (poate fi "scăzut" prin XOR, coeficientul în cât este 1). Dacă nu, se continuă fără scădere cu următoarea iterație (cifra din cât este 0). Cum ne interesează doar restul, nu trebuie să reținem câtul; calculul se încheie când au fost consumați toți biții din deîmpărțit (textul dat).
În cazul particular al standardului POSIX, suma de control se calculează pe 32 de biți, iar polinomul de grad 32 folosit ca împărțitor are următorii biți pe 1 (coeficienți): 32, 26, 23, 22, 16, 12, 11, 10, 8, 7, 5, 4, 2, 1, 0. (Asemenea polinoame se aleg pentru proprietățile bune de detectare a erorilor). Șirul de biți codificat e format din caracterele textului, în ordine, fiecare începând cu bitul cel mai semnificativ; apoi lungimea textului, în caractere, pe numărul minim necesar de octeți, începând cu cel mai puțin semnificativ; apoi 32 de biți 0 (4 caractere nule). Suma de control e restul pe 32 de biți, negat bit cu bit (pentru că, adăugată la mesaj, permite verificarea faptului că același algoritm ar trebui să dea restul 0).
Indicații: Din descrierea algoritmului, rezultă că vom manipula un număr pe 32 de biți (restul curent), de exemplu un long. Testul valorii 1 pentru bitul cel mai semnificativ trebuie făcut înainte de deplasarea la stânga, care va provoca dispariția lui. Din același motiv, nu vom reprezenta bitul 32 al împărțitorului, calculele descrise ținând cont implicit că acesta e 1. Împărțirea poate fi făcută pas cu pas, pe măsură ce se citesc caractere din text, însă nu poate începe până când în deîmpărțitul inițial nu s-au acumulat 32 de biți (4 caractere), și e disponibil încă un caracter din care șă se "aducă" biții următori. La sfârșitul textului, se continuă algoritmul cu octeții reprezentând lungimea textului, și cei 4 octeți finali de zero (care ne asigură că deîmpărțitul va avea >= 32 de biți chiar dacă textul e mai scurt).
Textul poate fi citit la alegere, fie până la linie nouă, fie până la sfârșit de fișier, cu un ciclu de tipul

 while ((c = getchar()) != EOF) { /* prelucreazâ c */ }
unde c e declarat ca int. Rezultatul poate fi verificat prin comparație cu programul UNIX cksum.
Marius Minea
Last modified: Fri Nov 12 09:00:00 EET 2010