La rappresentazione dei numeri

prof. Matteo Lugli

Created: 2024-04-05 ven 18:48

Introduzione

Il computer non usa il sistema decimale per rappresentare le informazioni

Il sistema posizionale usato e' quello binario, come probabilmente sapete gia'.

Domanda: perche' secondo voi?

Metodo atomico


"Dividi il sapere in atomi di verita' per comprendere il tutto"

L'informazione elettronica di acceso-spento, o segnale-nessun segnale, e' l'informazione piu' semplice che possiamo produrre con un circuito.

Rappresentazione in base \(\beta\)

Formalizziamo la rappresentazione di un numero in base \(\beta\):

\begin{align} N &= (c_{p}, c_{p-1}, ..., c_0)_{\beta} \\ &= c_{p}\beta^p+ c_{p-1}\beta^{p-1}+...+c_1\beta c_0 \end{align}

In base 10:

\begin{equation} (237)_{10} = 2\cdot10^2+ 3 \cdot 10^1+ 7 \cdot 10 ^ 0\\ \end{equation}

Similmente, in base 2….

\begin{align} (11101101)_{2} &= 1 \cdot 2^7 + \\ &1 \cdot 2^6 +\\ &1 \cdot 2^5 +\\ &0 \cdot 2^4 + \\ &1 \cdot 2^3 + \\ &1 \cdot 2^2 + \\ &0 \cdot 2^1 + \\ &1 \cdot 2^0 \end{align}

Algoritmo delle divisioni successive:


Serve per rappresentare un intero positivo \(\alpha \in \mathcal{N}\) da base 10 ad una diversa base \(\beta\).

Consiste nell'eseguire la divisione intera (operatore // in Python) del numero \(\alpha\) per \(\beta\) finche' non si giunge ad un quoziente nullo, tenendo traccia del resto della divisione.

Esercizio

Implementare l'algoritmo delle divisioni successive in Python (dato un intero \(n\), restituire la rappresentazione binaria.)

Algoritmo delle moltiplicazioni successive:


Serve per rappresentare la parte decimale di un numero in una base \(\beta > 1\).

Chiamiamo \(p\) la funzione che prende solo la parte intera di un numero reale dato in input;

\begin{align} &\text{Input}: \alpha=0.a_{1}a_{2}... , \beta \\ &\textbf{while } alpha != 0: \\ & \quad \quad D \leftarrow = d(\alpha) \\ & \quad \quad alpha \leftarrow D \cdot \beta \\ & \quad \quad \text{write}(I(\alpha)) \\ \end{align}

Numeri fixed point


Il formato fixed point e' usato dal calcolatore per rappresentare gli interi in memoria (\(x \in \mathbb{Z}\))

Il calcolatore ha a disposizione \(t+1\) bit per rappresentare i valori. Ad esempio, per \(t+1=16\):
\(N = 1235 = (10011010011)_{2}\)

Rappresentazione dei negativi

In \(\mathbb{Z}\) abbiamo anche i numeri negativi: per rappresentare un \(N\) negativo si seguono i seguenti step:

Si rappresenta \(|N|\) sui \(t+1\) bit disponibili;

Si "flippano" tutti i bit;

Si somma 1 al risultato

Perche' cosi' tanta fatica quando avremmo potuto usare semplicemente un bit per il segno?

\begin{equation} 1235 + (-1235) = 0 \end{equation}

\begin{equation} + \end{equation}

\begin{equation} = 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \end{equation}

Esercizio

Avendo a disposizione 4 bit, qual'e' il range di valori che possiamo rappresentare?

Soluzione

L'intervallo rappresentabile e' [-8, 7]

Piu' in generale… [-2t, 2t-1]

La morale e' che avendo a disposizione "spazio" limitato, non possiamo rappresentare tutti i numeri!

Esercizio

Provare a rappresentare -9, 23 e -25 avendo a disposizione soltanto 4 bit.

Soluzione

Overflow e Underflow


Se proviamo a rappresentare numeri troppo grandi o troppo piccoli, ricadiamo nel problema dell'underflow o dell' overflow.

Se proviamo a effettuare operazioni tra numeri il cui risultato esce dall'intervallo \([-2^{t}, 2^{t}-1]\) si ha perdita di informazione, quindi si commette un errore!

Numeri floating point


Per rappresentare i numeri reali, e' opportuno avere un metodo che sia flessibile e non sprechi bit;

Se degli 8 bit che abbiamo a disposizione ne assegnamo 5 alla parte intera e 3 alla parte decimale e vogliamo rappresentare un numero con tante cifre dopo la virgola e poche prima della virgola, stiamo "sprecando" dei bit;

La rappresentazione floating point e' usata dal calcolatore per risolvere il problema.

Intuizione


Cerchiamo di rappresentare i valori con la virgola in notazione scientifica:

\begin{equation} 123.456 = 1.23456 \cdot 10^{2} \end{equation}

Similmente,

\begin{equation} 01010.00110 = 1.01000110 \cdot 2^{3} \end{equation}

Segno, Esponente, Mantissa (1/2)


Segno, Esponente, Mantissa (2/2)


IEEE-754


Come gestiamo gli esponenti negativi?
Ad esempio:

\begin{equation} (0.375)_{10} = (0.0110...0)_{2} = (1.10...0) \cdot 2^{-2} \end{equation}

Segno: positivo \(\rightarrow\) 0

Mantissa: \(1.1...0 \rightarrow 10...0\)

Esponente: \(-2 \rightarrow -2 = -127 + 125\)

Quindi per l'esponente iniziamo a contare da \(-127\), in modo da riuscire a rappresentare anche i numeri negativi

Quindi l'esponente che dobbiamo usare e' 125.

Quindi la rappresentazione e' la seguente: