Codul direct, codul invers şi cel complementar

Un număr zecimal poate fi reprezentat unic în orice sistem poziţional de numeraţie, inclusiv în cel binar (cu baza 2), existând o corespondenţă biunivocă între aceste reprezentări. Acest fapt este esenţial pentru calculatoarele moderne, în care numerele sunt reprezentate prin coduri binare.

Să remarcăm, că am specificat coduri binare şi nu, pur şi simplu, numere binare – secvenţa de cifre binare poate avea diverse semnificaţii în funcţie de codul (codificarea) folosit(ă).

Mă voi referi în continuare la numerele întregi în limbajul C. Numerele întregi pot fi descrise ca date de tip char, short int, int şi long. Se mai aplică modificatorul unsigned care specifică că datele sunt de tip întreg nenegative (fără semn). Pentru reprezentarea datelor de tip întreg se folosesc fragmente de memorie (se alocă un număr finit de biţi):

1 octet (8 biţi) – char,
2 octeţi (16 biţi) – unsigned int, short int, int,
4 octeţi (32 de biţi) – long, unsigned long.

Este clar că folosind un număr finit de biţi, putem reprezenta un număr finit de numere întregi (de pe un interval mărginit).

Să explicăm acest lucru pornind în primul rând de la numerele întregi nenegative care folosesc pentru reprezentare coduri de n biţi.

Cel mai mic număr nenegativ care poate fi reprezentat pe n biţi este 0 şi codul lui binar conţine n zerouri 00…0. Cel mai mare număr care poate fi reprezentat pe n biţi conţine în toate poziţiile unităţi, adică are forma 11…1. În sistemul zecimal acest număr are valoarea S=1*2n-1+1*2n-2+…+1*21+1*20. Efectuăm mici transformări prin înmulţirea ambelor părţi cu 2 şi adunarea şi scăderea în membrul drept a câte o unitate. Obţinem:

2S=2n+2n-1+…+21+1-1 =(2n-1)+(2n-1+2n-2+…+21+20).

Remarcăm că a doua paranteză este egală de fapt cu S. Prin urmare 2S=2n-1+S şi S=2n-1 şi am demonstrat următoarea afirmaţie.

Propoziţia 1. Pe n biţi pot fi reprezentate 2n numere întregi nenegative ce aparţin intervalului de valori [0, 2n-1].

Să remarcăm că la aceeaşi concluzie putem ajunge şi dacă observăm ca numărul imediat următor lui 11…1 este format din 1 pe poziţia superioară urmat de n zerouri. Valoarea zecimală a ultimului număr este 2n. Rezultă că precedentul număr este pur şi simplu 2n-1, anume acel S care figurează mai sus.

Folosind formula din Propoziţia 1 putem calcula intervalele de valori pentru numerele întregi nenegative reprezentate pe:

1 octet – [0, 28-1]=[0, 255];
2 octeţi (16 biţi) – [0, 216-1]=[0, 65 535];
4 octeţi (32 de biţi) – [0, 232-1]=[0, 4 294 967 295].

Nota Bene. Numerele întregi nenegative se reprezintă prin numere binare obişnuite, numite coduri directe (nu se folosesc careva reguli deosebite de codificare – codul coincide cu binarul).

Dacă dorim să reprezentăm şi numere negative, trebuie să observăm că pentru aceasta putem folosi aceleaşi secvenţe de cifre binare, care s-au folosit mai sus. Altele nu sunt.

Spre exemplu, în cazul unui octet din cele 256 de numere binare, jumătate: de la 0000 0000 la 0111 1111 le vom folosi pentru reprezentarea lui zero şi a numerelor de la 1 la 127, iar restul: de la 1000 0000 până la 1111 1111 le vom folosi pentru reprezentare numerelor negative. Anume aici apare necesitatea de a codifica numerele negative. Să observăm că poziţia superioară, cea din stânga, este egală cu 1 pentru toate numerele negative. Prin urmare, bitul superior (din stânga) poate fi interpretat şi ca bit de semn. Dacă e 0, numărul este pozitiv. Dacă e 1, numărul este negativ. Am putea folosi o schemă de codificare, numită cod direct,  prin care numerele negative să aibă pe prima poziţie din stânga 1, iar în rest să se folosească reprezentarea obişnuită binară (apare un singur inconvenient cu codul 1000 0000 care va fi rezervat pentru -128, neîncadrându-se în schema generală).

Totuşi, în calculatoare se folosesc scheme de codificare puţin mai complexe. Pentru zero şi numerele pozitive reprezentarea rămâne cea naturală/obişnuită binară (codul direct). Pentru numerele negative codificarea porneşte de la numărul pozitiv opus (de la codul direct), se inversează valoarea fiecărui bit (0 se schimbă cu 1, iar 1 se schimbă cu 0) şi se obţine aşa numitul cod invers. La acest cod invers se adaugă un 1 binar, adică se adaugă numărul 0000 0001 şi se obţine codul complementar (cod complementar faţă de 1).

Exemplu. Pentru a obţine codul complementar al numărului -1, pornim de la codul direct 0000 0001 al numărului 1. Inversăm fiecare bit şi obţinem codul invers 1111 1110. La acest număr (cod invers) se adaugă 1 , adică codul 0000 0001. Obţinem codul invers 1111 1111 al numărului -1.

0000 0001 – codul direct al numărului 1,
1111 1110 – codul invers al numărului -1,
+
0000 0001
1111 1111 – codul complementar al numărului -1.

De ce se foloseşte codul complementar? O explicaţie simplă poate rezulta dacă observăm că adunarea 1 şi -1 trebuie să dea ca rezultat 0. Acest rezultat se obţine în mod natural la adunarea codului direct al numărului 1 şi a celui complementar pentru numărul -1. Ţinem cont că se folosesc doar 8 biţi şi unitatea care trebuie transferată pe poziţia a 9-a pur şi simplu se pierde 😉

Remarcă. Codul complementar Cn(N) pe n biţi al unui număr întreg negativ N poate fi obţinut şi în baza formulei: Cn(N)=Cn+1(2n)-Cn(|N|).

Aşadar, deosebim trei tipuri de coduri, în fiecare dintre ele codurile pentru zero şi numerele pozitive fiind aceleaşi, iar pentru numerele negative:

  1. Codul direct are pe poziţia superioară (prima poziţie din stânga) 1 iar în rest coincide cu reprezentarea obişnuită binară a numărului opus (pozitiv);
  2. Codul invers se obţine din codul direct al numărului opus pozitiv prin inversarea valorii fiecărui bit;
  3. Codul complementar se obţine din codul invers prin adunarea unei unităţi la bitul inferior (bitul din dreapta).

În baza Propoziţiei 1, dar şi a celor expuse supra, reiese următoarea propoziţie:

Propoziţia 2. Pe n biţi pot fi reprezentate 2n numere întregi care aparţin intervalului de valori [-2n-1, 2n-1-1].

Folosind formula din Propoziţia 2 putem evidenţia intervalele de valori pentru numerele întregi reprezentate pe:

1 octet – [27, 27-1]=[-128, 127];
2 octeţi (16 biţi) – [-215, 215-1]=[-32 768, 32 767];
4 octeţi (32 de biţi) – [-231, 231-1]=[-2 147 483 648, 2 147 483 647].

În final să subliniem că aceste coduri: direct, invers şi complementar, nu sunt unicele posibile. Dacă raţionăm în mod abstract fără careva restricţii de eficienţă a codificării, atunci pentru 22n numere pe n poziţii binare există circa 22n modalităţi de codificare 🙂

Anunțuri

3 comentarii la “Codul direct, codul invers şi cel complementar

  1. Pingback: Codul direct, codul invers şi cel complementar - Ziarul toateBlogurile.ro

  2. Nu sunt matematician si nu voi deveni, probabil, dar va intreb: cum ar fi un calcul al oricarui numar intr-o reprezentare geometrica. Adica daca acest numar nu ar avea o forma strict plana si ar fi un fel de complex de entitati plasate intr-un context spatial (macar imaginar). Cum s-ar roti aceste numere unele in functie de celelalte, operatiile lor de ce forme de calcul ar deprinde. In fond cele 3 mentionate de dumneavoastra s-ar aplica, dar ce ar fi nou ca si calcul? Viteza rotatiei numarului in spatiu? Ar avea noi proprietati matematice, precum o gravitatie, o viteza de rotire, una de atractie…
    Nu stiu daca am fost suficient de clar, dar poate este o idee si un puzzle nou pentru dumneavoastra.
    Ma bucur ca v-am citit

  3. Numărul este o categorie abstractă! Codul lui ţine de reprezentarea lui! Am scris în articolele precedente despre diverse sisteme de numeraţie şi alte codificări. Concluzia de bază din ele – pot există o infinitate de siteme de numeraţie, oricât de bizară ar părea iniţial această afirmaţie. Întrebarea ta o înţeleg anume în acest context – al unui sistem de numeraţie în care numerele să fie reprezentate prin entităţi spaţiale. Eu aş mai putea adăuga şi alte idei, cum ar fi entităţile muzicale (notele sunt cifrele), entităţile de culori etc. Evident că efectuarea operaţiilor în aşa sisteme ar putea fi imaginată în diverse moduri.
    Cele trei coduri de mai sus ţin de sistemul binar, în primul rând, şi de calculatoarele moderne.
    Oricum ideile pe care le-ai evidenţiat sunt interesant şi într-un anumit context poate că ar putea fi cumva realizate.

Lasă un răspuns

Completează mai jos detaliile tale sau dă clic pe un icon pentru a te autentifica:

Logo WordPress.com

Comentezi folosind contul tău WordPress.com. Dezautentificare / Schimbă )

Poză Twitter

Comentezi folosind contul tău Twitter. Dezautentificare / Schimbă )

Fotografie Facebook

Comentezi folosind contul tău Facebook. Dezautentificare / Schimbă )

Fotografie Google+

Comentezi folosind contul tău Google+. Dezautentificare / Schimbă )

Conectare la %s