2010-08-10 13 views
9

Sto cercando di capire meglio l'aritmetica in virgola mobile e ho visto alcuni collegamenti a "Ciò che ogni scienziato informatico dovrebbe sapere sull'aritmetica in virgola mobile".Come rappresentare 0,1 in virgola mobile aritmetica e decimale

Non riesco ancora a capire come un numero come 0.1 o 0.5 sia memorizzato nei float e come decimali.

Qualcuno può spiegare come è strutturata la memoria?

So che il galleggiante è costituito da due parti (ad esempio un numero dalla potenza di qualcosa).

risposta

35

Ho sempre puntato le persone verso Harald Schmidt's online converter, insieme con il Wikipedia IEEE754-1985 article con le sue belle foto.

Per questi due valori specifici, si ottiene (per 0,1):

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm 1/n 
0 01111011 10011001100110011001101 
      | || || || || || +- 8388608 
      | || || || || |+--- 2097152 
      | || || || || +---- 1048576 
      | || || || |+------- 131072 
      | || || || +-------- 65536 
      | || || |+----------- 8192 
      | || || +------------ 4096 
      | || |+---------------  512 
      | || +----------------  256 
      | |+-------------------  32 
      | +--------------------  16 
      +-----------------------  2 

Il segno è positivo, che è abbastanza facile.

L'esponente è 64+32+16+8+2+1 = 123 - 127 bias = -4, quindi il moltiplicatore è 2-4 o 1/16.

La mantissa è grande. Consiste di 1 (la base implicita) più (per tutti quei bit con valore uguale a 1/(2n) come n inizia a 1 e aumenta a destra), {1/2, 1/16, 1/32, 1/256, 1/512, 1/4096, 1/8192, 1/65536, 1/131072, 1/1048576, 1/2097152, 1/8388608}.

Quando si aggiungono tutti questi, si ottiene 1.60000002384185791015625.

Quando si moltiplica per il moltiplicatore, si ottiene 0.100000001490116119384765625, ed è per questo che dicono non si può rappresentare 0.1 esattamente come float IEEE754, e offre così tante opportunità sul SO per le persone rispondendo alle domande "why doesn't 0.1 + 0.1 + 0.1 == 0.3?" -tipo :-)


L'esempio di 0,5 è sostanzialmente più semplice. Viene rappresentato come:

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm 
0 01111110 00000000000000000000000 

che significa che è la base implicita, 1, più altri additivi (tutti i bit di mantissa sono pari a zero).

Il segno è di nuovo positivo. L'esponente è 64+32+16+8+4+2 = 126 - 127 bias = -1. Quindi il moltiplicatore è 2-1 che è 1/2 o 0.5.

Quindi il valore finale è 1 moltiplicato per 0.5 o 0.5. Ecco!


Qualche volta ho trovato più facile pensare di esso in termini di decimali.

Il numero 1.345 è equivalente a

1 + 3/10 + 4/100 + 5/1000 

o:

 -1  -2  -3 
1 + 3*10 + 4*10 + 5*10 

Analogamente, la rappresentazione IEEE754 per decimali 0.8125 è:

s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm 
0 01111110 10100000000000000000000 

Con la base implicita di 1, che è equivalente a il binario:

  01111110-01111111 
1.101 * 2 

o:

     -1 
(1 + 1/2 + 1/8) * 2  (no 1/4 since that bit is 0) 

che diventa:

(8/8 + 4/8 + 1/8) * 1/2 

e poi diventa:

13/8 * 1/2 = 0.8125 
2

Vedi the Wikipedia entry e the IEEE group, prima.

Fondamentalmente, c'è un segno, un numero e un esponente. Un numero in una base non può essere rappresentato finitamente in un'altra base se la base di partenza ha fattori non presenti nella base di destinazione. Ad esempio, 1/3 non può essere rappresentato come numero decimale finito, ma è banale da rappresentare come numero ternario (base-3): (0,1) .

Quindi 0.5 ha una rappresentazione finita binario (0,1) , cioè 2 -1, ma ha un 0,1 ripetendo rappresentazione perché 2 e 10 hanno un fattore (5) non in Comune.

Problemi correlati