Qualcuno può spiegare la rappresentazione del galleggiante in memoria?


20

Questa non è una domanda duplicata mentre leggo la domanda precedente.

Qualcuno può aiutarmi a capire how float values are stored in the memory.

Il mio dubbio è che qui i valori float contengono ' .'( for example 3.45) come '.'sarà rappresentata la memoria?

Qualcuno può chiarirmi con un diagramma?


21
Che ne dici della fonte meno attesa, Wikipedia? en.wikipedia.org/wiki/Floating_point#Internal_representation
9000

4
E puoi aggiungere l'articolo principale: IEEE virgola mobile
mouviciel

4
Se sei come me e ti piace imparare giocando con le cose, inserendo input e ricevendo output, ecc., Visita
KChaloux,

Esiste una vasta gamma di formati a virgola mobile, tutti diversi. Il virgola mobile IEEE è il più comune al giorno d'oggi, ma non è l'unico. Quando ero studente, dovevo imparare il formato a virgola mobile CDC 6600, e aveva alcuni vantaggi rispetto a IEEE, il più grande dei quali era 48 bit di mantissa per precisione singola. L'IEEE è limitato a circa 24 bit di mantissa per precisione singola, motivo per cui ogni classe introduttiva di metodi numerici in questi giorni dice agli studenti "Usa sempre il doppio, non il float".
John R. Strohm,

Vedi floating-point-gui.de e ricorda
quell'URL

Risposte:


44

Il punto decimale non viene memorizzato in modo esplicito da nessuna parte; questo è un problema di visualizzazione.

La seguente spiegazione è una semplificazione; Sto tralasciando molti dettagli importanti e i miei esempi non intendono rappresentare alcuna piattaforma del mondo reale. Dovrebbe darti un'idea di come i valori in virgola mobile sono rappresentati in memoria e le problematiche ad essi associate, ma vorrai trovare fonti più autorevoli come Ciò che ogni scienziato informatico dovrebbe sapere sull'aritmetica in virgola mobile .

Inizia rappresentando un valore in virgola mobile in una variante della notazione scientifica, usando la base 2 anziché la base 10. Ad esempio, il valore 3.14159 può essere rappresentato come

    0.7853975 * 2 2

0.7853975 è il significato , ovvero la mantissa; è la parte del numero che contiene le cifre significative. Questo valore viene moltiplicato per la base 2 elevata alla potenza di 2 per ottenere 3,14159.

I numeri in virgola mobile vengono codificati memorizzando il significato e l'esponente (insieme a un bit di segno).

Un tipico layout a 32 bit è simile al seguente:

 3 32222222 22211111111110000000000
 1 09876543 21098765432109876543210
+-+--------+-----------------------+
| |        |                       |
+-+--------+-----------------------+
 ^    ^                ^
 |    |                |
 |    |                +-- significand 
 |    |
 |    +------------------- exponent 
 |
 +------------------------ sign bit

Come i tipi interi con segno, il bit di ordine superiore indica segno; 0 indica un valore positivo, 1 indica negativo.

I successivi 8 bit vengono utilizzati per l'esponente. Gli esponenti possono essere positivi o negativi, ma invece di riservare un altro bit di segno, sono codificati in modo tale che 10000000 rappresenta 0, quindi 00000000 rappresenta -128 e 11111111 rappresenta 127.

I bit rimanenti vengono utilizzati per il significato. Ogni bit rappresenta una potenza negativa di 2 conteggi da sinistra, quindi:

    01101 = 0 * 2 -1 + 1 * 2 -2 + 1 * 2 -3 + 0 * 2 -4 + 1 * 2 -5 
          = 0,25 + 0,125 + 0,03125 
          = 0.40625

Alcune piattaforme assumono un bit iniziale "nascosto" nel significato e sempre impostato su 1, quindi i valori nel significato sono sempre compresi tra [0,5, 1). Ciò consente a queste piattaforme di memorizzare valori con una precisione leggermente maggiore (maggiori informazioni su quelle di seguito). Il mio esempio non lo fa.

Quindi il nostro valore di 3.14159 sarebbe rappresentato come qualcosa del genere

    0 10000010 11001001000011111100111
    ^ ^ ^
    | | |
    | | + --- significato = 0.7853975 ...
    | |
    | + ------------------- esponente = 2 (130-128)
    |
    + ------------------------- segno = 0 (positivo)

    valore = -1 (segno) * 2 (esponente) * (significato)
    valore = -1 0 * 2 2 * 0.7853975 ...
    valore = 3.14159 ...

Ora, qualcosa che noterai se sommi tutti i bit nel significato è che non ammontano a 0,7853975; in realtà escono a 0.78539747. Non ci sono abbastanza bit per memorizzare esattamente il valore ; possiamo solo memorizzare un'approssimazione. Il numero di bit nel significato determina la precisione o quante cifre significative è possibile memorizzare. 23 bit ci danno circa 6 cifre decimali di precisione. I tipi a virgola mobile a 64 bit offrono abbastanza bit nel significato per fornire circa 12-15 cifre di precisione. Ma tieni presente che ci sono valori che non possono essere rappresentati esattamente, non importa comemolti bit che usi. Proprio come valori come 1/3 non possono essere rappresentati in un numero finito di cifre decimali, valori come 1/10 non possono essere rappresentati in un numero finito di bit. Poiché i valori sono approssimativi, anche i calcoli sono approssimativi e si accumulano errori di arrotondamento.

Il numero di bit nell'esponente determina l' intervallo (i valori minimo e massimo che è possibile rappresentare). Ma man mano che ci si sposta verso i valori minimo e massimo, aumenta la dimensione del divario tra valori rappresentabili. Cioè, se non puoi rappresentare esattamente valori compresi tra 0,785397 e 0,785398, allora non puoi rappresentare esattamente né valori compresi tra 7,85397 e 7,85398, o valori compresi tra 78,5397 e 78,5398 o valori tra 785397,0 e 785398,0. Fai attenzione quando moltiplichi numeri molto grandi (in termini di grandezza) per numeri molto piccoli.


"ma invece di riservare un altro bit di segno" Quello che stai descrivendo è il comportamento esatto di un intero con segno.
Simon,

6

Il .non è memorizzato affatto. Innanzitutto, dovresti comprendere la notazione ingegneristica, che ha un fattore di precisione fissa e un esponente intero: 1è 1.0 · 10 0 = 1.0E0, 2 è 2.0E0, 10 è 1.0E1ecc. Ciò consente una notazione molto breve di grandi numeri. Un miliardo è 1.0E9. Il fattore prima del Esolito è notata come un numero a precisione fissa: 1.00000E9. Un risultato di ciò è che il numero un miliardo e uno = 1.000.000.001 e un miliardo sono entrambi uguali in questa notazione, quando la precisione non è abbastanza grande. Si noti inoltre che il fattore non ha mai bisogno di uno zero iniziale. Invece, l'esponente può essere ridotto fino a quando non è più il caso.

In memoria, un numero in virgola mobile è rappresentato in modo simile: un bit ha il segno, alcuni bit formano il fattore come un numero a precisione fissa ("mantissa"), i bit rimanenti formano l'esponente. Differenze significative rispetto alla notazione ingegneristica di base 10 è che, ovviamente, ora l'esponente ha base 2. La dimensione esatta di ogni parte dipende dall'esatto standard in virgola mobile che si sta utilizzando.


3
Questa è "notazione scientifica". La "notazione ingegneristica" è quando l'esponente è limitato a multipli di 3.
Clemente J.,

7
Che la base 2 sia usata è molto importante. Determina quali valori possono essere memorizzati esattamente e quali non lo sono, e anche se non si può essere disturbati a sviluppare un'intuizione per quali valori (lo so non posso) si dovrebbe almeno ricordare che le cifre decimali sono completamente inutili modo di pensare ai galleggianti.

1
@delnan: se aiuta, ogni bit nella mantissa è la metà di quello superiore. Quindi, i galleggianti possono immagazzinare somme di poteri negativi di due: 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128 e così via, fino al limite della mantissa . Quindi il epsilon in un 32-bit floatè 2^-22 * exponent, o circa 1/4194304.
Greyfade,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.