LA CODIFICA LORENZO BRACCIALE [email protected] LA CODIFICA • Serve per rappresentare un’informazione • La stessa informazione rappresentata in modi diversi • ad es. 200 o “duecento” • Stessa rappresentazione per informazioni diverse • ad es. “fare” (it) / “fare” (eng.) • Utilizza i simboli di un alfabeto • ad esempio alfabeto fonetico, binario • combinandoli • in “codici” • associando un codice ad un’entità di informazione LA CODIFICA BINARIA • Alfabeto: 0 – 1 • bit – BInary digiT – “base 2” • Utilizzata largamente per rappresentare informazioni su dispositivi elettronici • Non molto “human friendly” • A che numero equivale 010010 ? • Se pensiamo a come è composto il numero decimale 1234: 4*100+3*101+2*102+1*104 • Quindi 0*20+1*21+0*22+0*23+1*24+0*25 = 24 + 2 = 18 • Come scomponiamo in binario il numero decimale 43? LA CODIFICA BINARIA • Come scomponiamo in binario il numero decimale 43? parte intera divisione per due resto divisione per due 43 1 21 1 10 0 5 1 2 0 1 1 0 43 = 101011 meno significativo LA CODIFICA BINARIA • Quanti oggetti diversi codifichiamo con X bit? • 2X • Quanti bit servono per codificare N oggetti? • Intero superiore di Log2N • Esercizi: • Codificare il numero 121 in binario • Codificare il numero 121/2 (divisione intera) in binario • Codificare il numero 121 * 4 in binario CODIFICA ESADECIMALE • La rappresentazione binaria è ostica per gli uomini • • 10100110 00110000 • Ma la conversione in decimale non è immediata… Spesso quindi si usa la rappresentazione esadecimale • • • • base 16: alfabeto: 0123456789abcdef 4 bit – un carattere esadecimale Usata molto spesso (codifica RGB, indirizzi di memoria, mac address etc) • il numero di prima diventa: a6 30 (2 byte, 16 bit) Spesso la base usata si indica nel prefisso • 0xa630 • • 0b1010011000110000 Esercizio: • Codificare in binario 0xEA10 LA CODIFICA ESADECIMALE Decimale Binario Esadecimale 0 0000 0 1 0001 1 2 0010 2 3 0011 3 4 0100 4 5 0101 5 6 0110 6 7 0111 7 8 1000 8 9 1001 9 10 1010 a 11 1011 b 12 1100 c 13 1101 d 14 1110 e 15 1111 f E I NUMERI NEGATIVI? • Fin’ora abbiamo visto la rappresentazione di numeri senza segno (unsigned) • Aggiungiamo un bit! • rappresentazione “modulo e segno” (truemagnitude) • possiamo rappresentare meno numeri: 2k-1 • Il bit più significativo se è 1, allora il numero è negativo modulo segno 1 1 0 1 in decimale: -10 • Problemi • doppia rappresentazione dello 0 • addizione e sottrazione più complicata 0 RAPPRESENTAZIONE IN COMPLEMENTO A 1 • Uguale alla rappresentazione “modulo e segno” ma se il numero è negativo vengono negati tutti i bit del modulo • • • • 5 5 -5 -5 = 0101 (modulo e segno) = 0101 (complemento a 1) = 1101 (modulo e segno) = 1010 (complemento a 1) RAPPRESENTAZIONE IN COMPLEMENTO A 2 • Come complemento a 1 ma se il numero è negativo allora si somma 1 alla loro rappresentazione • 010 = 00002 • -110 = 11112 • rappresentiamo -510 in compl. a 2 • • • 510 è 01012 Complementiamo tutti i bit (compl. a 1) à 10102 Aggiungiamo 1 à 1011 • Una sola rappresentazione dello 0 • Intervallo asimmetrico: [-2n-1 , 2n-1 -1] • Somma e differenza più semplici • Ma dobbiamo prima introdurre l’overflow per capire il perchè OVERFLOW • Le somme tra numeri binari avvengono come le somme tra numeri decimali • Prendiamo due interi (unsigned) di 4 bit: 510 e 310 0101 + 0011 = 1000 • Cosa succede se sommiamo 12 e 8 ? • Non bastano 4 bit per rappresentare il risultato • Overflow (trabocco), il resto viene perso • Risultato: 0100 (ovvero 410) 1100 + 1000 = 10100 ADDIZIONI IN COMPLEMENTO A 2 Basta fare la somma: • L’overflow ci permette di sommare i numeri negativi 15 0000 1111 -7 1111 1001 8 0000 1000 l’ultimo riporto viene ignorato (overflow) 64 0100 0000 70 0100 0110 -122 1000 0110 Se sommo numeri con lo stesso segno ed ottengo un numero con segno opposto, allora sono andato in overflow (spesso è un errore) GLI INTERI NEL C Dipendenti dall’architettura (esempio valori tipici) Type N bits tipici Codifica Min Max signed short 16 compl. 2 -32.768 32.767 unsigned short 16 Senza segno 0 65.535 signed int 32 compl. 2 –2.147.483.648 2.147.483.647 unsigned int 32 Senza segno 0 signed long 32 Compl. 2 –2.147.483.648 2.147.483.647 Unsigned long 32 Senza Segno 0 4.294.967.295 4.294.967.295 RAPPRESENTAZIONE DIPENDENTE/ INDIPENDENTE DALL’HARDWARE • Char, short, int, long: la rappresentazione dipende dall’hardware • Per sapere la grandezza: sizeof(int) • Per alcuni utilizzi sono disponibili dei fixed-size typedef • int32_t : intero 32 bit (esattamente) • uint8_t : intero 8 bit (esattamente) • int64_t : intero 64 bit (esattamente) include <stdint.h> DOV’E’ IL BUG? /* voglio stampare 256 volte la stringa “ciao” */ uint8_t i = 0; while (i<256) { i = i + 1; print(“ciao”); } LIMITS.H In limits.h troviamo le definizioni dei massimi/minimi numeri rappresentabili • Dipendenti dalle architetture • SHRT_MIN, SHRT_MAX, INT_MIN, INT_MAX, LONG_MIN, LONG_MAX, USHRT_MAX, UINT_MAX e ULONG_MAX Per sapere con quanti byte viene rappresentato un tipo: • printf(“Intero: %d bytes\n”, sizeof(int)); Esercizio sommare due numeri immessi dall’utente ed avvertire in caso di overflow NUMERI IN VIRGOLA MOBILE • Un numero non intero può essere rappresentato in diversi modi utilizzando la notazione esponenziale: • 14.5 = 1.45 * 10 = 0.145 * 102 = 145 * 10-1 • Rappresentazione in virgola mobile (floating point) • E’ necessaria una rappresentazione di riferimento (normalizzata) • ad es. parte intera rappresentata da una sola cifra • Un numero non intero puo’ essere quindi rappresentato da una mantissa (ad es. 1.45) e un esponente da dare alla base (ad es. 1) 14.5 = 1.45 X 101 NUMERI IN VIRGOLA MOBILE • Nel caso dei numeri binari • dato che la parte intera possiamo ometterla risparmiando spazio • la base è 2 • …ed il segno • Abbiamo la possibilità di overflow (numero troppo grande) e underflow (numero troppo piccolo) STANDARD IEEE-754 • Standard internazionale più diffuso per i numeri reali • Numeri normalizzati e non normalizzati (se esp = 1) • La rappresentazione di “infinito” (positivo o negativo) • La rappresentazione di NaN (Not a number), come risultato ad esempio di 0 / 0 • Bit segno: 0 positivo, 1 negativo • Anche l’esponente ha il suo segno • • introduzione del bias: +127 per riutilizzare l’hardware per la comparazione di int compl 2. float 32bit Segno Esponente 1bit 8bit Mantissa 23bit STANDARD IEEE-754 • Esempio: • -5,82812510 = 101.1101012 = 1.011101012 X 22 mantissa 01110101 1 10000001 segno esponente esponente 2 + 127 = 129 01110101 0000 0000 0000 000 mantissa NUMERI IN VIRGOLA MOBILE Dipendenti dall’architettura (esempio valori tipici) Type Codifica Dimensione Min Max float IEEE 754 32 bit ±1.17 x 10-38 ±3.4 x 10+38 double IEEE 754 64 bit (11 bit exp, 52 mantissa) ±2.2 x 10-308 ±1.7 x 10+308 long double Estensione 80 bit IEEE 754 a 80 bit ±3.4 x 10-4932 ±1.1 x 10+4932 • Float.h contiene i valori minimi e massimi rappresentabili: • FLT_MIN, FLT_MAX, DBL_MIN, DBL_MAX, LDBL_MIN, LDBL_MAX PRINTF guida completa: http://www.cplusplus.com/reference/cstdio/printf/ %[flags][width][.precision][length]specifier Specificatore Output Esempio d oppure i Signed decimal integer -123 u Unsigned decimal integer 1331 x Unsigned hexadecimal integer 7fa X Unsigned hexadecimal integer (maiuscolo) 7FA f Decimal floating point 12.55 e Scientific notation (mantissa/esponente) 3.3 e+2 c Character a s Stringa ciao p Puntatore a055ff0 ESERCIZIO Create un programma che converta un numero da base 2, 10 o 16 in un altro numero in base 2, 10 o 16. Consiglio: • Utilizzare scanf per accettare decimale (%d) ed esadecimale (%x) • Utilizzare scanf per accettare un numero binario come long unsigned int