Rappresentazione binaria dei dati
In questa pagina 6
In memoria tutto è una sequenza di bit; il significato (intero, reale, carattere, istruzione) dipende da come il programma la interpreta. Questo spiega comportamenti che si vedono nei tipi di Python e C: overflow degli int in C, 0.1 + 0.2 != 0.3, dimensione delle stringhe in byte.
Basi di numerazione
Un numero in base con cifre vale
| Base | Cifre | Prefisso Python/C | Esempio (= 45) |
|---|---|---|---|
| 2 | 0–1 | 0b |
0b101101 |
| 8 | 0–7 | 0o (Python), 0 (C) |
0o55 |
| 10 | 0–9 | — | 45 |
| 16 | 0–9, A–F | 0x |
0x2D |
- Da base 10 a base 2: divisioni successive per 2, i resti letti dal basso verso l'alto. , quindi .
- Base 2 ↔ 16: ogni cifra esadecimale corrisponde a 4 bit (). Per questo gli indirizzi di memoria e i byte si scrivono in esadecimale.
bin(45), oct(45), hex(45) # ('0b101101', '0o55', '0x2d')
int("101101", 2) # 45
int("2d", 16) # 45Con bit si rappresentano configurazioni: 8 bit → 256, 16 → 65 536, 32 → circa .
Interi senza segno
Con bit: valori da a . Somma binaria in colonna con riporto; se il risultato non sta in bit si ha overflow e il bit di riporto finale si perde (il risultato è preso modulo ).
Interi con segno: complemento a 2
Con bit il bit più significativo ha peso negativo :
- Intervallo: da a (8 bit: da a ). Asimmetrico: c'è un negativo in più.
- Bit più significativo = 1 ⇔ numero negativo. Lo zero ha una sola rappresentazione.
- Opposto di un numero: si invertono tutti i bit e si somma 1. Esempio a 8 bit: , inverto → , +1 → .
- La sommatrice è la stessa degli interi senza segno: è il motivo per cui il complemento a 2 si usa ovunque.
- Overflow: sommando due numeri dello stesso segno si ottiene un risultato di segno opposto. A 8 bit: .
In Python gli int hanno precisione arbitraria: niente overflow, 2**100 è esatto. In C gli interi hanno dimensione fissa (tipicamente int a 32 bit) e l'overflow sui tipi con segno è comportamento indefinito (vedi Tipi, operatori e controllo del flusso in CTipi interi e reali del C con dimensioni e limiti, conversioni implicite e cast, divisione intera, operatori di incremento, logici e bit a bit; if, switch, while, do-while, for, break e continue.Tipi, operatori e controllo del flusso in C →).
Numeri reali: virgola mobile (IEEE 754)
Un reale è rappresentato come :
| Formato | Bit totali | Segno | Esponente | Mantissa | Cifre decimali circa |
|---|---|---|---|---|---|
singola precisione (float in C) |
32 | 1 | 8 (bias 127) | 23 | 7 |
doppia precisione (float in Python, double in C) |
64 | 1 | 11 (bias 1023) | 52 | 15–16 |
Conseguenze:
- Solo i numeri della forma sono esatti. in binario è periodico, quindi è approssimato.
- La precisione è relativa: la distanza tra due float consecutivi cresce con il valore.
- Valori speciali:
inf,-inf,nan(risultato di operazioni indefinite;nan != nan).
0.1 + 0.2 == 0.3 # False
0.1 + 0.2 # 0.30000000000000004
import math
math.isclose(0.1 + 0.2, 0.3) # True: confronto con tolleranza
1e308 * 10 # infRegola: mai confrontare float con ==; usare una tolleranza (math.isclose o abs(a - b) < eps).
Caratteri e testo
- ASCII: 7 bit, 128 caratteri (lettere inglesi, cifre, punteggiatura, controllo).
'A'= 65,'a'= 97,'0'= 48: le lettere e le cifre sono consecutive. - Unicode: assegna un numero (code point) a ogni carattere di ogni lingua (
'è'= U+00E8 = 232,'€'= U+20AC). - UTF-8: codifica Unicode in 1–4 byte; i caratteri ASCII occupano 1 byte ed hanno lo stesso codice. È la codifica standard per i file di testo.
ord("A"), chr(97) # (65, 'a')
len("è"), len("è".encode("utf-8")) # (1, 2): 1 carattere, 2 byteIn C un char è 1 byte e una stringa è un array di byte: una lettera accentata in UTF-8 occupa più char (vedi Array e stringhe in CArray di dimensione fissa in memoria contigua, inizializzazione, nessun controllo sugli indici, passaggio a funzioni con la lunghezza, matrici; stringhe come array di char terminati da '\0' e funzioni di string.h.Array e stringhe in C →).
Errori tipici
- Dimenticare che nel complemento a 2 l'intervallo è asimmetrico (, non ).
- Usare
==tra float o usare float per quantità che devono essere esatte (es. importi in centesimi: meglio interi). - Confondere il numero di caratteri di una stringa con il numero di byte che occupa codificata.