Formulario di Codifica e Aritmetica Binaria

Indice dei contenuti

    Formulario di codifica e aritmetica binaria per i corsi di base di informatica. Lo scopo è offrire un riferimento autosufficiente e ragionato, centrato sui calcoli e sulle procedure, per convertire tra sistemi di numerazione, eseguire l’aritmetica binaria, rappresentare numeri con segno, in virgola fissa e mobile, codificare caratteri e dati, e manipolare espressioni booleane.

    Perché tutto questo è il fondamento dell’informatica? Un calcolatore non “conosce” i numeri decimali, le lettere o le immagini: conosce solo due stati fisici, convenzionalmente 0 e 1, perché un circuito è molto più affidabile se deve distinguere fra due soli livelli (acceso/spento, alto/basso) anziché fra dieci. Tutta l’informazione — numeri, testo, suoni, istruzioni — viene quindi codificata in sequenze di bit. Capire come si rappresentano e si elaborano questi bit è capire come “ragiona” la macchina.

    Sono trattati solo argomenti con formule e procedure di calcolo verificabili; i concetti puramente descrittivi (architetture, reti, algoritmi, sistemi operativi) sono nel glossario. Ogni sezione contiene esempi numerici svolti passo passo e commentati.

    L’ordine consigliato è:

    1. sistemi di numerazione e valore posizionale;
    2. conversioni tra basi;
    3. aritmetica binaria (somma, sottrazione, prodotto, shift);
    4. numeri con segno e complemento a due;
    5. overflow e propagazione dell’errore;
    6. virgola fissa e virgola mobile (IEEE 754);
    7. codici: BCD, Gray, ASCII, Unicode;
    8. unità di misura dei dati;
    9. algebra di Boole;
    10. forme canoniche e mappe di Karnaugh.

    Mappa di lettura operativa:

    ProblemaStrumento principaleControllo
    valore di un numero in base bvalore posizionalebase e peso delle cifre
    convertire una basedivisioni/moltiplicazioni successiveparte intera e frazionaria
    sommare o sottrarre in binarioriporto / prestito o complementonumero di bit
    numeri negativicomplemento a duebit di segno
    risultato fuori intervallorilevazione di overflowriporto sui bit di segno
    numeri realivirgola fissa o IEEE 754segno, esponente, mantissa
    caratteri e simbolitabelle di codificaASCII, Unicode, UTF-8
    capacità di datipotenze di 2 e di 10prefissi binari vs decimali
    semplificare logicaalgebra di Boole, Karnaughtavola di verità

    1. Sistemi di numerazione e valore posizionale

    L’idea di sistema posizionale

    In un sistema posizionale il valore di una cifra dipende dalla sua posizione. Lo facciamo ogni giorno in base 10: nel numero 327, il 3 non vale tre ma trecento, perché occupa la posizione delle centinaia. La stessa idea si generalizza a qualunque base b: ogni posizione ha un peso pari a una potenza crescente di b, da destra verso sinistra.

    Formalmente, un numero in base b con cifre d_i vale:

    N = \sum_{i=-m}^{n-1} d_i \cdot b^{\,i}

    dove gli indici positivi pesano la parte intera (unità b^0, poi b^1, b^2, …) e quelli negativi la parte frazionaria (b^{-1}, b^{-2}, …). La base b determina quante cifre distinte servono: da 0 a b-1. In base 2 bastano due simboli, ed è questa economia di simboli a renderla adatta all’elettronica.

    Le basi più usate in informatica:

    BaseNomeCifrePerché si usa
    2binaria0, 1due stati fisici affidabili
    8ottale0–7compatta i bit a gruppi di 3
    10decimale0–9naturale per l’uomo
    16esadecimale0–9, A–Fcompatta i bit a gruppi di 4

    L’esadecimale merita una nota: si usa moltissimo non perché la macchina “pensi” in base 16, ma perché è una scrittura compatta del binario comoda per l’uomo. Un byte (8 bit) si scrive con due sole cifre esadecimali, molto più leggibili di otto 0 e 1.

    Esempio commentato con parte frazionaria

    Il numero 101{,}11_2 si valuta sommando ogni cifra moltiplicata per il peso della sua posizione. Le posizioni a sinistra della virgola hanno peso 2^0, 2^1, 2^2; quelle a destra 2^{-1}, 2^{-2}:

    1\cdot2^2 + 0\cdot2^1 + 1\cdot2^0 + 1\cdot2^{-1} + 1\cdot2^{-2} = 4 + 0 + 1 + 0{,}5 + 0{,}25 = 5{,}75_{10}

    Si noti che 2^{-1} = 0{,}5 e 2^{-2} = 0{,}25: in binario la parte frazionaria è una somma di mezzi, quarti, ottavi, e così via. Questo fatto, apparentemente innocuo, è la radice di un problema importante (sezione 6): non tutti i decimali “tondi” sono esprimibili esattamente in binario.

    2. Conversioni tra basi

    Da base b a decimale

    È la conversione più semplice: si applica direttamente il valore posizionale, sommando i prodotti cifra × peso. La difficoltà, in esadecimale, è solo ricordare che le lettere valgono A=10, B=11, \dots, F=15. Esempio, 2\text{F}_{16}:

    2\cdot16^1 + 15\cdot16^0 = 32 + 15 = 47_{10}

    Da decimale a base b — parte intera (divisioni successive)

    Il metodo si basa su un’osservazione: dividere un numero per la base b dà come resto la cifra meno significativa, e come quoziente il numero “senza” quella cifra. Ripetendo, si estraggono una a una tutte le cifre, dalla meno alla più significativa. Per questo il risultato si legge dal basso verso l’alto.

    Esempio, 47_{10} in binario:

    DivisioneQuozienteResto
    47 \div 2231
    23 \div 2111
    11 \div 251
    5 \div 221
    2 \div 210
    1 \div 201

    Leggendo i resti dal basso: 47_{10} = 101111_2. Verifica rapida (riconvertendo): 32+8+4+2+1 = 47. ✓

    Da decimale a base b — parte frazionaria (moltiplicazioni successive)

    Per la parte frazionaria il meccanismo è speculare: moltiplicando per b, la parte intera del risultato è la cifra frazionaria più significativa; si prosegue con la sola parte frazionaria residua, leggendo le cifre dall’alto verso il basso.

    Esempio, 0{,}625_{10} in binario:

    MoltiplicazioneRisultatoParte intera
    0{,}625 \times 21,251
    0{,}25 \times 20,50
    0{,}5 \times 21,01

    Il processo si ferma quando la parte frazionaria diventa 0: 0{,}625_{10} = 0{,}101_2. Ma non sempre finisce: provando con 0{,}1_{10} il calcolo non termina mai e produce una sequenza periodica (0{,}0\overline{0011}_2). Questo è il motivo profondo per cui 0{,}1 + 0{,}2 \ne 0{,}3 esatto nei calcolatori: 0{,}1 non è rappresentabile in modo finito in binario.

    Binario ↔ esadecimale ↔ ottale

    Queste conversioni sono immediate perché 16 = 2^4 e 8 = 2^3: una cifra esadecimale “vale” esattamente 4 bit, una ottale 3 bit. Basta raggruppare i bit, partendo dalla virgola:

    \underbrace{1011}_{\text{B}}\,\underbrace{0110}_{6} {}_2 = \text{B6}_{16}, \qquad \underbrace{010}_{2}\,\underbrace{110}_{6}\,\underbrace{110}_{6}{}_2 = 266_8

    Se i bit non sono multipli di 4 (o 3), si completano con zeri a sinistra. Questa corrispondenza esatta è la ragione pratica per cui esadecimale e ottale sono i formati preferiti per leggere contenuti di memoria.

    3. Aritmetica binaria

    Somma con riporto

    La somma binaria segue le stesse regole della decimale, ma con sole due cifre. Il caso chiave è 1+1: dà 0 con riporto di 1 alla posizione successiva (come 9+1=10 in decimale).

    0+0=0, \quad 0+1=1, \quad 1+1=10, \quad 1+1+1=11

    Esempio commentato, 1011_2 + 0110_2 (cioè 11+6):

      1011   (riporti)
       1011
     + 0110
     ------
      10001

    Da destra: 1+0=1; 1+1=10 (scrivo 0, riporto 1); 0+1+1=10 (scrivo 0, riporto 1); 1+0+1=10 (scrivo 0, riporto 1); resta il riporto finale 1. Risultato 10001_2 = 17. ✓

    Sottrazione con prestito

    La sottrazione bit a bit usa il prestito (borrow): il caso critico è 0-1, che dà 1 “prendendo in prestito” 1 dalla posizione successiva. In pratica, però, i calcolatori non implementano un circuito di sottrazione separato: trasformano A - B in A + (-B) usando il complemento a due (sezione 4). Così un unico sommatore esegue sia somme sia differenze, semplificando enormemente l’hardware. È un esempio di come una buona rappresentazione (il complemento a due) elimini la necessità di una macchina dedicata.

    Moltiplicazione

    La moltiplicazione binaria è più semplice della decimale, perché ogni cifra del moltiplicatore è 0 o 1: ogni prodotto parziale è quindi o zero, o una copia del moltiplicando opportunamente shiftata. Esempio, 101_2 \times 11_2 (cioè 5 \times 3):

        101
      x  11
      -----
        101    (101 x 1)
       101     (101 x 1, shiftato)
      -----
       1111

    Risultato 1111_2 = 15. ✓ La moltiplicazione si riduce dunque a una sequenza di shift e somme, ed è così che la realizzano i circuiti.

    Shift come moltiplicazione e divisione per potenze di 2

    Una proprietà preziosa: in qualunque base posizionale, “spostare” le cifre equivale a moltiplicare o dividere per la base. In binario, spostare a sinistra di k posizioni (aggiungendo k zeri a destra) moltiplica per 2^k; spostare a destra divide:

    N \times 2^k = N \ll k, \qquad N \div 2^k = N \gg k

    Esempio: 0011_2 = 3, shiftato a sinistra di 2 → 1100_2 = 12 = 3 \times 4. Poiché lo shift è una delle operazioni più veloci della CPU, i compilatori sostituiscono automaticamente le moltiplicazioni e divisioni per potenze di 2 con shift: è la forma più classica di ottimizzazione a basso livello.

    4. Numeri con segno e complemento a due

    Il problema: come rappresentare il segno

    Con soli 0 e 1 non esiste un “segno meno” da scrivere: anche il segno va codificato in bit. Sono state inventate tre soluzioni, di sofisticazione crescente:

    MetodoIdeaSvantaggio
    Modulo e segnoun bit dedicato al segno, il resto è il modulodue zeri (+0 e -0), somma complicata
    Complemento a unoil negativo si ottiene invertendo tutti i bitancora due zeri
    Complemento a dueinversione dei bit, più 1nessuno (standard universale)

    Il problema di modulo e segno è che il circuito di somma deve “guardare” i segni e decidere se sommare o sottrarre: complicato. Il complemento a due elimina questo problema.

    Complemento a due: definizione e perché funziona

    Per ottenere il negativo di un numero su n bit si invertono tutti i bit e si aggiunge 1:

    -N = (\overline{N} + 1) \bmod 2^n

    Esempio su 8 bit, calcolo di -5:

    1. 5 = 00000101;
    2. inverto tutti i bit: 11111010;
    3. aggiungo 1: 11111011.

    Quindi -5 = 11111011 in complemento a due a 8 bit. Il bit più significativo (MSB) funge da segno: 0 = positivo, 1 = negativo. Perché funziona? Perché in aritmetica modulo 2^n vale N + (\overline{N}+1) = 2^n \equiv 0: la definizione garantisce che N + (-N) = 0, esattamente ciò che ci si aspetta da un opposto. Verifica: 00000101 + 11111011 = 1\,00000000, e l’1 in più (nono bit) “trabocca” fuori dagli 8 bit, lasciando 00000000. ✓

    Intervallo rappresentabile e proprietà

    Su n bit, il complemento a due copre:

    -2^{n-1} \le N \le 2^{n-1} - 1

    Su 8 bit: da -128 a +127. L’intervallo è asimmetrico: c’è un valore negativo in più (-128) che non ha opposto positivo rappresentabile. Questo è fonte di un classico bug: calcolare -(-128) su 8 bit restituisce di nuovo -128 (overflow). I vantaggi che compensano l’asimmetria sono due e decisivi: un solo zero (niente -0), e soprattutto la possibilità di eseguire la sottrazione come sommaA - B = A + (-B) — con un unico circuito sommatore, senza logica speciale per il segno.

    5. Overflow e propagazione dell’errore

    Overflow nella somma in complemento a due

    L’overflow si verifica quando il risultato di un’operazione esce dall’intervallo rappresentabile: i bit a disposizione non bastano, e il risultato è scorretto. La regola di rilevazione è elegante: c’è overflow se i due operandi hanno lo stesso segno e il risultato ha segno opposto. Sommando due positivi non si può ottenere un negativo (se accade, è overflow); idem per due negativi. Equivalentemente, c’è overflow se il riporto entrante nel bit di segno differisce da quello uscente.

    Esempio su 8 bit: 100 + 50 = 150. Ma il massimo rappresentabile è 127: il risultato in complemento a due diventa 10010110_2, che ha l’MSB a 1, quindi appare negativo (-106). Due positivi che danno un negativo: overflow rilevato. Nota importante: l’overflow nei numeri con segno è diverso dal semplice riporto uscente (carry) nei numeri senza segno — sono due bandiere distinte nella CPU.

    Errore nei reali e epsilon di macchina

    I numeri reali, rappresentati con un numero finito di bit, non possono essere infinitamente precisi: nasce un errore di arrotondamento a ogni operazione, che può accumularsi in calcoli lunghi. La grandezza di riferimento è l’epsilon di macchina \varepsilon, definito come il più piccolo numero tale che, nella rappresentazione usata:

    1 + \varepsilon \ne 1

    Misura la “risoluzione relativa” della rappresentazione: in doppia precisione \varepsilon \approx 2{,}2\times10^{-16}, cioè circa 16 cifre decimali significative. Conoscere \varepsilon serve a capire quando un calcolo perde precisione (per esempio sottraendo due numeri quasi uguali, fenomeno detto cancellazione catastrofica).

    6. Virgola fissa e virgola mobile

    Virgola fissa

    Nella virgola fissa si decide a priori quanti bit destinare alla parte intera e quanti alla frazionaria; la virgola “non si muove”. È semplice, veloce e usata in sistemi embedded e DSP, ma ha intervallo e risoluzione rigidi: con pochi bit frazionari non si rappresentano numeri molto piccoli, con pochi interi non si rappresentano numeri grandi.

    Virgola mobile (IEEE 754): l’idea

    Per rappresentare con gli stessi bit sia numeri minuscoli sia enormi, si adotta la virgola mobile, l’analogo binario della notazione scientifica (6{,}02\times10^{23}). Un numero si scrive come segno × mantissa × base elevata a un esponente; “muovendo” l’esponente, la virgola scorre. Lo standard universale è l’IEEE 754:

    N = (-1)^{s} \times (1 + m) \times 2^{(e - bias)}

    dove s è il bit di segno, m la mantissa frazionaria, e l’esponente memorizzato, bias uno spostamento fisso che permette di rappresentare esponenti sia positivi sia negativi senza un secondo segno.

    FormatoBitSegnoEsponenteMantissaBias
    Singola (float)321823127
    Doppia (double)64111521023

    L’1 iniziale della mantissa (la cifra prima della virgola dopo la normalizzazione) è sempre 1, quindi non si memorizza: è il “bit nascosto”, che regala un bit di precisione gratuito.

    Esempio svolto passo passo: -6{,}5 in singola precisione

    1. Converto in binario: 6{,}5_{10} = 110{,}1_2 (cioè 4+2+0{,}5).
    2. Normalizzo (una sola cifra non nulla prima della virgola): 1{,}101 \times 2^{2}.
    3. Segno: il numero è negativo, quindi s = 1.
    4. Esponente memorizzato: l’esponente reale è 2; sommando il bias, e = 2 + 127 = 129 = 10000001_2.
    5. Mantissa: la parte dopo la virgola della forma normalizzata, 101, completata a 23 bit con zeri.

    Risultato finale (segno | esponente | mantissa):

    1 10000001 10100000000000000000000

    Valori speciali e insidie

    Lo standard riserva alcune configurazioni di bit a casi particolari: lo zero (in due forme, +0 e -0), gli infiniti (\pm\infty, risultato di overflow o di 1/0) e NaN (Not a Number, risultato di operazioni indefinite come 0/0 o \sqrt{-1}). Conseguenza pratica fondamentale: a causa della precisione finita e degli arrotondamenti, non si devono mai confrontare due float con l’uguaglianza diretta (a == b): si verifica invece che la loro differenza sia inferiore a una piccola tolleranza. Inoltre NaN ha una proprietà sorprendente: non è uguale a sé stesso (NaN != NaN), proprietà usata proprio per rilevarlo.

    7. Codici: BCD, Gray, ASCII, Unicode

    Finora abbiamo codificato numeri; ma in binario si codifica qualunque informazione, scegliendo una corrispondenza (un codice) tra simboli e sequenze di bit. La scelta del codice non è neutra: ogni codice ottimizza qualcosa.

    Codici numerici: BCD e Gray

    CodiceIdeaVantaggio
    BCDogni cifra decimale su 4 bit separaticonversione immediata da/verso decimale
    Graycodici consecutivi differiscono di 1 solo bitriduce errori di lettura

    Il BCD (Binary-Coded Decimal) codifica ogni cifra decimale con i suoi 4 bit, indipendentemente: 59_{10} = 0101\,1001_{BCD} (5 → 0101, 9 → 1001). Spreca codici (usa 10 delle 16 combinazioni a 4 bit) ma evita conversioni: utile in display, calcolatrici e sistemi che mostrano cifre decimali.

    Il codice Gray ha una proprietà speciale: due valori consecutivi differiscono per un solo bit. Nella numerazione binaria normale, passare da 0111 (7) a 1000 (8) cambia 4 bit insieme; se questi non commutano simultaneamente in un sensore meccanico, si leggono valori spuri. Il Gray elimina il problema, ed è per questo usato negli encoder di posizione e nell’ordinamento delle mappe di Karnaugh (sezione 10).

    Codifica dei caratteri

    CodificaBit/byteCaratteri
    ASCII7 bit128 simboli (alfabeto inglese, cifre, punteggiatura)
    ASCII esteso8 bit256 simboli (lettere accentate, ecc.)
    Unicode / UTF-81–4 bytetutti i sistemi di scrittura del mondo

    L’ASCII associa a ogni carattere un numero a 7 bit: ‘A’ = 65, ‘Z’ = 90, ‘a’ = 97, ‘0’ = 48. La tabella è progettata con cura: cifre e lettere sono in sequenza contigua, quindi valgono trucchi utilissimi come '7' - '0' = 7 (per convertire un carattere-cifra nel suo valore) e una differenza costante di 32 tra maiuscole e minuscole ('a' - 'A' = 32), che permette di cambiare maiuscolo/minuscolo con una semplice operazione.

    L’ASCII basta per l’inglese ma non per le altre lingue. Unicode assegna un numero (code point) a ogni carattere di ogni scrittura esistente. UTF-8 è la codifica più diffusa di Unicode: usa un numero variabile di byte (1 per i caratteri ASCII, fino a 4 per i più rari), ed è retrocompatibile con ASCII — un testo ASCII è già un testo UTF-8 valido. Questa retrocompatibilità è la ragione del suo dominio sul web.

    8. Unità di misura dei dati

    Bit, byte e numero di bit necessari

    L’unità elementare è il bit (0 o 1); 8 bit formano un byte, l’unità di indirizzamento tipica della memoria. Con n bit si rappresentano 2^n configurazioni distinte. Invertendo la relazione, per rappresentare V valori (o simboli) distinti servono:

    n = \lceil \log_2 V \rceil \quad \text{bit}

    Esempio: per codificare le 26 lettere dell’alfabeto servono \lceil \log_2 26 \rceil = \lceil 4{,}7 \rceil = 5 bit (4 bit darebbero solo 16 simboli, insufficienti). Questa formula è la base per dimensionare campi, indirizzi e codici.

    Prefissi binari e decimali: la confusione delle “K”

    Qui si annida un equivoco diffusissimo. I prefissi (kilo, mega, giga…) possono indicare potenze di 10 (sistema SI) o di 2 (sistema IEC, introdotto per chiarezza):

    Decimale (SI)ValoreBinario (IEC)Valore
    kB (kilobyte)10^3 = 1000KiB (kibibyte)2^{10} = 1024
    MB10^6MiB2^{20}
    GB10^9GiB2^{30}
    TB10^{12}TiB2^{40}

    La differenza è piccola sui kilobyte (1024 vs 1000, +2,4%) ma cresce con la scala. Su un terabyte è circa il 10%: ecco perché un disco venduto “da 1 TB” (10^{12} byte, conteggio del produttore) appare come circa 0{,}91 TiB nel sistema operativo (che conta in potenze di 2). Non è un inganno né un errore: sono due convenzioni diverse sullo stesso numero di byte.

    9. Algebra di Boole

    L’algebra di Boole è la matematica dei due valori logici (vero/falso, 1/0). È il fondamento del progetto dei circuiti digitali: ogni funzione che un calcolatore esegue, in ultima analisi, è una combinazione di operazioni booleane realizzate da porte logiche.

    Operatori fondamentali

    OperatoreNotazioneRisultato
    NOT\overline{A}inverte il valore
    ANDA \cdot B1 solo se entrambi 1
    ORA + B1 se almeno uno è 1
    XORA \oplus B1 se i due sono diversi

    Le notazioni \cdot (prodotto) per l’AND e + (somma) per l’OR non sono casuali: l’AND si comporta come la moltiplicazione (1\cdot1=1, tutto il resto 0) e l’OR come una somma “satura” (0+0=0, il resto 1). Questa analogia rende intuitive molte leggi.

    Leggi fondamentali

    LeggeForma
    IdentitàA + 0 = A, \;A \cdot 1 = A
    Elemento nulloA + 1 = 1, \;A \cdot 0 = 0
    IdempotenzaA + A = A, \;A \cdot A = A
    ComplementoA + \overline{A} = 1, \;A \cdot \overline{A} = 0
    Doppia negazione\overline{\overline{A}} = A
    De Morgan\overline{A+B} = \overline{A}\cdot\overline{B}
    De Morgan\overline{A\cdot B} = \overline{A}+\overline{B}
    DistributivaA(B+C) = AB + AC
    AssorbimentoA + AB = A

    Queste leggi servono a semplificare le espressioni logiche, e quindi a ridurre il numero di porte (e di costo) di un circuito. Le leggi di De Morgan sono le più importanti in pratica: dicono come negare un’espressione composta, trasformando AND in OR e viceversa. La loro conseguenza tecnologica è enorme: poiché si possono esprimere AND, OR e NOT usando solo porte NAND (o solo NOR), queste due porte sono dette universali, e molti circuiti reali sono costruiti interamente con NAND, più economiche da fabbricare.

    10. Forme canoniche e mappe di Karnaugh

    Dalla tavola di verità alla formula

    Qualunque funzione booleana è completamente descritta dalla sua tavola di verità (l’elenco delle uscite per ogni combinazione di ingressi). Da essa si ricava sempre una formula, in due forme canoniche equivalenti:

    • somma di prodotti (SOP): si prende l’OR di un termine AND per ogni riga con uscita 1 (i mintermini);
    • prodotto di somme (POS): si prende l’AND di un termine OR per ogni riga con uscita 0 (i maxtermini).

    La forma canonica è corretta ma spesso ridondante: contiene più termini del necessario. Da qui l’esigenza di minimizzarla.

    Mappe di Karnaugh: minimizzare graficamente

    La mappa di Karnaugh è uno strumento grafico per ottenere l’espressione minima (meno termini, meno variabili) senza manipolazioni algebriche. Si dispongono i valori di uscita in una griglia le cui righe e colonne sono ordinate con codice Gray, così che celle adiacenti differiscano per un solo bit di ingresso. Si raggruppano poi gli 1 in blocchi rettangolari di dimensione potenza di 2 (1, 2, 4, 8\dots), il più grandi possibile, eventualmente a cavallo dei bordi (la mappa “si avvolge”). Ogni volta che un gruppo raddoppia, una variabile si elimina, perché nel gruppo quella variabile compare sia vera sia negata.

    Esempio: una funzione di due variabili F(A,B) che vale 1 quando AB = 01 e AB = 11. In entrambi i casi B = 1 (mentre A cambia): raggruppando le due celle adiacenti, A si elide e resta semplicemente:

    F = B

    Si è passati da una somma di due prodotti (\overline{A}B + AB) a una sola variabile: è esattamente ciò che la legge \overline{A}B + AB = B(\overline{A}+A) = B dimostra algebricamente, ma la mappa lo rende immediato a occhio. Su 3 o 4 variabili il vantaggio grafico diventa decisivo.

    Note d’uso ed errori comuni

    • Nella conversione decimale→base, leggere i resti dal basso (parte intera) e le parti intere dall’alto (parte frazionaria): invertirli è l’errore più frequente.
    • Frazioni decimali semplici come 0{,}1 sono periodiche in binario: la rappresentazione è approssimata, ed è la causa di errori inattesi nei confronti tra reali.
    • Una cifra esadecimale = 4 bit esatti, una ottale = 3 bit: sfruttarlo per conversioni rapide da/verso binario.
    • Nel complemento a due l’intervallo è asimmetrico: -2^{n-1} non ha opposto positivo, e -(-2^{n-1}) dà overflow.
    • Overflow con segno: stesso segno degli operandi, segno opposto del risultato. È diverso dal carry dei numeri senza segno.
    • I float hanno precisione finita: mai confronti di uguaglianza diretti, usare una tolleranza; ricordare \pm\infty e NaN (con NaN \ne NaN).
    • Distinguere prefissi decimali (kB, 10^3) da binari (KiB, 2^{10}): è l’origine della discrepanza tra capacità dichiarata e mostrata dei dischi.
    • ASCII: cifre e lettere sono contigue ('5'-'0'=5, maiuscole/minuscole differiscono di 32); UTF-8 è a lunghezza variabile e retrocompatibile con ASCII.
    • Applicare De Morgan con cura: la negazione di una somma è il prodotto delle negazioni, non la somma delle negazioni.
    • Nelle mappe di Karnaugh, fare i gruppi più grandi possibile (e potenza di 2): gruppi più grandi = espressione più semplice.

    Ultimo aggiornamento: