Qual è il numero più piccolo possibile? – Programmazione Parola del Giorno

Marin Benčević
Marin Benčević

Seguire

Aug 7, 2018 · 5 min a leggere

Qual è il più piccolo numero maggiore di 0? Questa è una di quelle semplici domande con risposte complicate da qualche parte tra “non ce n’è” e “dipende”.

Se chiedi a un matematico, ti diranno che non può esserci un tale numero perché romperebbe la matematica. Se hai un numero n, dove n è il numero più piccolo dopo 0, allora non può esserci un numero n/2, perché n è già il più piccolo. Ciò significa che la divisione stessa si rompe, cosa che ai matematici non piace.

Se chiedi a un computer, otterrai effettivamente una risposta. Al contrario del mondo reale, i computer non hanno una quantità infinita di numeri perché semplicemente non potevano adattarsi. I computer memorizzano i numeri nei registri di memoria e ogni registro ha un numero fisso di bit. Immagina se avessi solo tre cifre. Il numero più grande che potresti rappresentare sarebbe 999. Questo è ciò che accade in un computer.

Ciò significa che l’insieme di numeri interi in un computer è limitato dal numero di cifre. In un computer, c’è sicuramente un numero maggiore (ad esempio, INT_MAX in C). È il numero con la quantità massima di cifre, che sono tutte impostate su un binario 1. Su un sistema a 8 bit, questo numero sarebbe 11111111.

Possiamo complicare ancora di più le cose includendo numeri negativi. Se abbiamo 8 bit di dati, possiamo usare il primo bit per rappresentare il segno del numero. 0 per più e 1 per meno. Ora abbiamo 7 bit per le nostre cifre, quindi il numero più grande è 011111111 che è più piccolo del nostro precedente numero più grande.

Non abbiamo ancora finito. Dobbiamo anche rappresentare numeri decimali. Anche se 0.12 è un numero piccolo, ha ancora tre cifre, proprio come 123. La differenza è che c’è un’altra cosa a cui dobbiamo pensare: il punto decimale, chiamato anche punto radix. Dobbiamo memorizzare sia le cifre che la posizione del punto radix.

Mentre gli interi sono limitati in quanto possono essere grandi, i numeri decimali sono limitati sia nelle dimensioni che nella precisione. Se hai un numero fisso di cifre, ci sono solo così tante cifre che puoi mettere dopo il punto decimale. Questo è il motivo per cui i computer devono arrotondare i numeri decimali.

Come memorizziamo questi numeri decimali, allora? I computer comprendono solo numeri interi, quindi abbiamo bisogno di un modo per memorizzare un numero decimale usando solo numeri interi.

Diciamo che abbiamo il numero 3.14. Iniziamo scrivendo le nostre tutte le cifre del numero. Otteniamo 314. E ‘ un inizio. Sappiamo che moltiplicando per potenze di 10, possiamo “spostare” il punto decimale attorno al numero. 314 * 10^-1 è 31.4, mentre 314 * 10^-2 è 3.14.

Tutto ciò di cui abbiamo bisogno per rappresentare il numero 3.14 sono tre numeri interi: 314, 10 e -2. 314 è quello che viene chiamato un significand, e questo è tutte le cifre del numero scritto.

10 è chiamato radix o base. Sappiamo che moltiplicando con potenze di 10 possiamo spostare il punto decimale attorno ai numeri in base 10. Lo stesso funziona per tutte le basi numeriche: in base 2 (o binario), è possibile spostare il punto moltiplicando per potenze di 2.

La potenza di cui ci spostiamo è chiamata esponente e ci dice dove si trova il punto decimale.

Puoi scrivere ogni numero decimale come quei tre numeri con una semplice formula:

number = significand * base^exponent3.14 = 314 * 10^-2
32.8 = 328 * 10^-1

Un computer memorizza un numero decimale memorizzando il segno, l’esponente e il significand in una singola stringa di cifre a 32 o 64 bit. Di solito c’è 1 bit per il segno, 11 bit per memorizzare l’esponente e 53 bit per memorizzare il significato, aggiungendo fino a 64.

Con questo in mente, torniamo alla nostra domanda: Qual è il più piccolo numero diverso da zero? Se abbiamo solo tre cifre da risparmiare, il numero più piccolo possibile è 0.01. Con quattro cifre, è 0.001. Noterai uno schema qui: il significato è sempre lo stesso, cambia solo l’esponente.

Quello di cui abbiamo bisogno è un significato di 1, perché è il più piccolo dopo 0. Dobbiamo quindi spostare il punto decimale il più lontano possibile a sinistra. Per fare ciò abbiamo bisogno del più piccolo (più negativo) esponente possibile.

Quanto piccolo, dipende dal layout del numero in memoria. Se abbiamo 11 bit per l’esponente, possiamo solo scrivere un numero lungo 10 bit, con 1 bit riservato per il segno. In un sistema a 64 bit l’esponente più piccolo è -308.

Alla fine, il numero più piccolo possibile in un sistema a 64 bit sarebbe intorno a 1 * 10^-308. E ‘ piccolo!

Abbiamo stabilito che esiste un numero più piccolo. Questo numero ci dice quanto possiamo fidarci del nostro computer. Se stai facendo qualcosa che richiede numeri molto grandi o numeri molto precisi, è necessario tenere a mente questo numero.

Quello che abbiamo appena calcolato è qualcosa chiamato l’unità nell’ultimo posto, o ulp, di 0. Oltre ad essere una parola davvero cool, ulp ci dice qual è la distanza minima tra due numeri in un computer. Abbiamo calcolato l’ulp di 0, che è la distanza minima tra 0 e il numero successivo.

Se si aggiunge il valore calcolato a 0 e si tenta di confrontarli, non saranno lo stesso numero. Tuttavia, se si aggiunge un valore inferiore all’ulp, sarebbe comunque lo stesso numero per quanto riguarda il computer.

print(0 == 0 + ulp(0)) // false
print(0 == 0 + ulp(0) / 2) // true

Per noi è ovvio che l’aggiunta di un valore diverso da zero a un numero produrrà un numero diverso, ma un computer deve arrotondare da qualche parte, quindi non può necessariamente dire se due numeri sono uguali.

Per confrontare più facilmente i sistemi informatici, usiamo l’ulp di 1 e la chiamiamo macchina epsilon. Una volta che si conosce la macchina epsilon, è possibile calcolare qualsiasi altro ulp con la seguente formula:

ulp(x) = machine epsilon * radix^exponent(x)

Il valore che abbiamo calcolato è molto piccolo, quindi probabilmente non raggiungerai quel limite durante la codifica. Ma, abbiamo calcolato il valore per 0. Con più cifre necessarie per il lato sinistro del punto decimale, meno abbiamo per il lato destro. Ciò significa che più grande è il numero, minore è la precisione che hai. In altre parole, l’ulp è una funzione diretta dell’esponente. Quando sposti il punto decimale verso destra, l’ulp aumenta e perdi precisione.

Spero che questa informazione ti aiuti la prossima volta che ricevi uno strano errore in virgola mobile nel tuo codice. Ricorda, i computer sono piuttosto potenti, ma anche un computer ha i suoi limiti.



+