2010-08-04 17 views

risposta

1

La definizione di punto fisso a 32 bit potrebbe variare. L'idea generale del punto fisso è che hai un numero fisso di bit prima e un altro numero fisso di bit dopo il punto decimale (o punto binario). Per uno a 32 bit, la divisione più comune è probabilmente pari (16 prima, 16 dopo), ma a seconda dello scopo non è garantito.

Per quanto riguarda la conversione, di nuovo è aperta a qualche variazione, ad esempio, se il numero di input non rientra nell'intervallo del target, è possibile che si desideri eseguire un numero qualsiasi di cose diverse (ad esempio, in alcuni casi avvolgente potrebbe avere senso, ma in altri potrebbe essere preferibile la saturazione).

1

Un tipo a virgola fissa è uno che ha un numero fisso di posizioni decimali/binari dopo il punto di radix. O più in generale, un tipo che può memorizzare multipli di 1/N per alcuni numeri interi positivi N.

Internamente, i numeri a virgola fissa vengono memorizzati come il valore moltiplicato per il fattore di scala. Ad esempio, 123.45 con un fattore di ridimensionamento di 100 viene memorizzato come se fosse il numero intero 12345.

Per convertire il valore interno di un numero a virgola fissa in virgola mobile, dividere semplicemente per il fattore di scala. Per convertire l'altro modo, moltiplicare per il fattore di scala e arrotondare al numero intero più vicino.

3

Un esempio molto semplice per la conversione in punto fisso, mostra come convertire e moltiplica PI per2. Il risultato viene riconvertito in doppio per dimostrare che la mantissa non è stata persa durante il calcolo con numeri interi.

Si potrebbe espandere facilmente con le tabelle di ricerca sin() e cos() ecc. Si consiglia di utilizzare il punto fisso per cercare una libreria di punti fissi Java.

public class Fix { 

    public static final int FIXED_POINT = 16; 
    public static final int ONE = 1 << FIXED_POINT; 

    public static int mul(int a, int b) { 
     return (int) ((long) a * (long) b >> FIXED_POINT); 
    } 

    public static int toFix(double val) { 
     return (int) (val * ONE); 
    } 

    public static int intVal(int fix) { 
     return fix >> FIXED_POINT; 
    } 

    public static double doubleVal(int fix) { 
     return ((double) fix)/ONE; 
    } 

    public static void main(String[] args) { 
     int f1 = toFix(Math.PI); 
     int f2 = toFix(2); 

     int result = mul(f1, f2); 
     System.out.println("f1:" + f1 + "," + intVal(f1)); 
     System.out.println("f2:" + f2 + "," + intVal(f2)); 
     System.out.println("r:" + result +"," + intVal(result)); 
     System.out.println("double: " + doubleVal(result)); 

    } 
} 

OUTPUT

f1:205887,3 
f2:131072,2 
r:411774,6 
double: 6.283172607421875 
+0

+1 per il metodo di moltiplicazione. Due suggerimenti per migliorare: offrire un arrotondamento quando si converte 'double' in fixed-point; e sovrascrive 'toString()' in modo che una corretta interpretazione del valore del punto fisso possa essere stampata facilmente (che è possibile utilizzare nel test). – MatthewD

16

Un numero a virgola fissa è una rappresentazione di un numero reale utilizzando un certo numero di bit di un tipo per la parte intera, e le rimanenti bit del tipo per la parte frazionaria. Il numero di bit che rappresentano ciascuna parte è fisso (da cui il nome, punto fisso). Un tipo intero viene in genere utilizzato per memorizzare valori a virgola fissa.

I numeri a virgola fissa vengono solitamente utilizzati in sistemi che non dispongono di supporto a virgola mobile o che richiedono una velocità maggiore di quella offerta da un punto variabile. I calcoli in virgola fissa possono essere eseguiti utilizzando le istruzioni di intere della CPU.

Un numero a virgola fissa a 32 bit verrebbe archiviato in un tipo a 32 bit come int.

Normalmente ogni bit in un (unsigned in questo caso) tipo intero rappresenterebbe un valore intero 2^n come segue:

1 0 1 1 0 0 1 0  = 2^7 + 2^5 + 2^4 + 2^1 = 178 
2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0 

Ma se il tipo è usato per memorizzare un valore a punto fisso, la bit sono interpretati in modo leggermente diverso:

1 0 1 1 0 0 1 0  = 2^3 + 2^1 + 2^0 + 2^-3 = 11.125 
2^3 2^2 2^1 2^0 2^-1 2^-2 2^-3 2^-4 

il numero punto fisso nel precedente esempio viene chiamato un numero 4,4 a virgola fissa, poiché ci sono 4 bit nella parte intera e 4 bit nella parte frazionaria del numero. In un tipo a 32 bit il valore a virgola fissa sarebbe in genere in formato 16.16, ma potrebbe anche essere 24.8, 28.4 o qualsiasi altra combinazione.

conversione da un valore a virgola mobile in un valore a virgola fissa prevede le seguenti fasi:

  1. Moltiplicare il galleggiante 2^(numero di bit frazionari per il tipo), ad es. 2^8 per 24.8
  2. Arrotondare il risultato (basta aggiungere 0,5) se necessario, e calcolarlo (o eseguire il cast su un tipo intero) lasciando un valore intero.
  3. Assegnare questo valore al tipo di punto fisso.

Ovviamente si può perdere un po 'di precisione nella parte frazionaria del numero. Se la precisione della parte frazionaria è importante, la scelta del formato a punto fisso può rispecchiare questo - ad es. utilizzare 16.16 o 8.24 anziché 24.8.

I valori negativi possono anche essere gestiti allo stesso modo se il numero di punto fisso deve essere firmato.

Se il mio Java fosse più forte, tenterei un po 'di codice, ma di solito scrivo tali cose in C, quindi non tenterò una versione Java. Inoltre, la versione stacker mi sembra buona, con la piccola eccezione che non offre la possibilità di arrotondare. Ti mostra anche come eseguire una moltiplicazione (lo spostamento è importante!)

+0

+1 per aver dedicato così tanto tempo a un argomento di questo "eroe non celebrato". – stacker

+0

Tutto corretto, e sarebbe meglio se tu fornissi una soluzione in modo che la tua risposta possa essere accettata. Fortunatamente, ho quello e ho intenzione di metterlo qui: int number = Float.floatToRawIntBits (floatNumber); – instcode

+0

Sto imparando anche questo punto fisso .. Nel tuo esempio, 10.125 * 10^4 = 178? È uguale a 162 invece. –

Problemi correlati