2012-08-25 12 views
18

Ho letto molto sui float, ma è tutto inutilmente coinvolto. Io penso li ho più o meno capito, ma c'è solo una cosa che vorrei sapere con certezza:Quali tipi di numeri sono rappresentabili in virgola mobile binario?

So che, frazioni di forma 1/pow(2,n), con n un intero, possono essere rappresentati esattamente in numeri in virgola mobile. Ciò significa che se aggiungo 1/32 a se stesso 32 milioni di volte, otterrei esattamente 1,000,000.

Che dire di qualcosa come 1/(32+16)? È uno sopra la somma di due poteri di due, funziona? O è 1/32+1/16 che funziona? È qui che sono confuso, quindi se qualcuno potesse chiarire che per me lo apprezzerei.

risposta

27

La regola può essere riassunta come segue:

  • Un numero può essere rappresentato esattamente in binario se la fattorizzazione prima del denominatore contiene soltanto 2. (cioè il denominatore è una potenza di due figli)

Quindi 1/(32 + 16) non è rappresentabile in binario perché ha un fattore 3 nel denominatore. Ma è 1/32 + 1/16 = 3/32.

Detto questo, ci sono più restrizioni da rappresentare in un tipo a virgola mobile. Ad esempio, hai solo 53 bit di mantissa in un IEEE double quindi 1/2 + 1/2^500 non è rappresentabile.

In questo modo è possibile eseguire una somma di potenze-di-due purché il range degli esponenti non superi più di 53 poteri.


generalizzare questo ad altre basi:

  • un numero può essere esattamente rappresentato in base 10 se la fattorizzazione prima del denominatore costituito da solo 2 e di 5 di.

  • Un numero razionale X può essere esattamente rappresentati nella base di N se la fattorizzazione prima del denominatore di X contiene solo numeri primi trovati nella fattorizzazione di N.

+3

Quindi, se ho capito bene, posso usare qualsiasi numero 'X/Y' finchè' Y' è una potenza di 2 e 'X' è un numero inferiore a' 2^53'? –

+2

Sì, è corretto. (salvo casi di sovra/underflow) – Mysticial

+0

@Mysticial: +1 per la risposta, ma ho un dubbio. 24/48 = 0,5, tuttavia secondo la regola precedente, non dovrebbe essere rappresentabile poiché 3 è uno dei fattori primi di 48, che non è uno dei 10 fattori primi. Perché? – legends2k

4

numeri a virgola mobile vengono letteralmente rappresentati usando il modulo:

1.m * 2^e 

Dove 1.m è una frazione binaria e e è un numero intero positivo o negativo.

Come tale, è possibile rappresentare 1/32 + 1/16 esattamente, come: (. 1.10 essendo la frazione binaria equivalente a 1,5)

1.1000000 * 2^-4 

1/48, tuttavia, non è rappresentabile in questo formato.

+0

(penso tu intenda "1.m * 2^e'.) – huon

+0

Derp. Sì, naturalmente. :) – duskwuff

+0

Non dovrebbe essere "1.1000000 * 2^-4'? – mkeiser

0

Un punto non ancora menzionato è che semanticamente, un numero in virgola mobile può essere considerato come rappresentativo di un intervallo di valori.L'intervallo di valori ha un punto centrale definito con precisione e la specifica IEEE generalmente richiede che il risultato di un calcolo a virgola mobile sia il numero il cui intervallo contiene il punto uno che otterrebbe operativo sui punti centrali dei numeri originali, ma nella sequenza:

 
    double N1 = 0.1; 
    float N2 = (float)N1; 
    double N3 = N2; 

N2 è la corretta rappresentazione singola precisione inequivocabile del valore che era stato rappresentato in N1, nonostante requisito stupido della lingua da utilizzare un cast esplicito. N3 rappresenterà uno dei valori che N2 potrebbe rappresentare (la specifica della lingua avviene per scegliere il valore double il cui intervallo è centrato al centro dell'intervallo dello float). Si noti che mentre N2 rappresenta il valore del suo tipo il cui intervallo contiene il valore corretto, N3 no.

Per inciso, la conversione di un numero da una stringa a una variabile in .net e .net lingue sembra passare attraverso una conversione intermedia a double, che a volte può alterare il valore. Ad esempio, anche se il valore 13571357 è rappresentabile come un float a precisione singola, il valore 13571357.499999999069f viene arrotondato a 13571358 (anche se è ovviamente più vicino a 13571357).

+0

1. "Il requisito sciocco della lingua per utilizzare un cast esplicito": di quale lingua stai parlando? C non richiede un cast qui ... – glglgl

+0

@glglgl: il codice di esempio citato sarebbe valido in C, Java o C#; le ultime due lingue richiedono entrambi il cast per 'float', sebbene non per' double'. – supercat

+0

Ok, grazie. Il commento 2. non si applica più, ho pensato alla conversione stringa -> double -> float, e sembra che tu abbia ragione. – glglgl

8

Un numero finito può essere rappresentato nel comune IEEE 754 formato a doppia precisione se e solo se è uguale a M • 2 e per alcuni interi M e posta in modo tale che -2 < M e -1074 ≤ e ≤ 971.

Per singola precisione, -2 < M e -149 ≤ e ≤ 104.

Per la precisione doppia, si tratta di conseguenze del fatto che il formato a doppia precisione utilizza 52 bit per memorizzare un significato e (che normalmente ha 53 bit a causa di un 1 implicito) e utilizza 11 bit per memorizzare un esponente. 11 bit codifica numeri da 0 a 2047, ma 0 e 2047 sono esclusi per scopi speciali e il numero codificato viene polarizzato di 1023, quindi rappresenta esponenti imparziali da -1022 a 1023. Tuttavia, questi esponenti imparziali sono per significati nell'intervallo [1, 2), e questi significati hanno frazioni. Per esprimere il significato come un intero, ho regolato l'intervallo di esponente per 52. La precisione singola è simile, con 23 bit per memorizzare un significante a 24 bit, 8 bit per l'esponente e un bias di 127.

Esprimere i numeri rappresentabili utilizzano un numero intero moltiplicato per una potenza di due anziché il più comune significato frazionale e semplificano la teoria dei numeri e altri ragionamenti sulle proprietà a virgola mobile. L'ho usato in questa risposta perché permette che l'insieme di valori rappresentabili sia espresso in modo conciso.

+0

Vedere questo è esattamente il tipo di "troppo profondamente coinvolto" che ho citato nella mia domanda ... –

+2

@Kolink: la risposta stessa è una singola frase che indica esattamente quali numeri possono e non possono essere rappresentati, usando solo i concetti familiari di numeri interi , moltiplicazione, poteri e meno di (o uguale a). Quanto più semplice di quello che puoi ottenere? Hai un numero intero di volte un potere di due, e il numero intero e il potere devono essere entro certi limiti. Il resto della risposta è solo una spiegazione su da dove viene la frase. –

+1

+1. Modificato per fissare i limiti superiori per e. –

Problemi correlati