Domanda

Sto facendo qualche virgola mobile aritmetica e di avere problemi di precisione.Il valore risultante è diversa nei due macchine per lo stesso ingresso.Ho letto il post @ Perché non posso moltiplicare un float? e leggere anche altro materiale sul web & capito che ha a che fare con la rappresentazione binaria in virgola mobile e sulla macchina epsilon.Tuttavia, ho voluto verificare se c'è un modo per risolvere questo problema e di Qualche lavoro in giro per l'aritmetica in virgola Mobile in C++ ??Sto convertendo un galleggiante unsigned short per la conservazione e sto convertendo indietro quando necessario.Tuttavia, quando ho convertire unsigned short, la precisione (a 6 cifre decimali) rimane corretta su una macchina, ma non su altri.

//convert FLOAT to short

unsigned short sConst = 0xFFFF;

unsigned short shortValue = (unsigned short)(floatValue * sConst);

//Convert SHORT to FLOAT

float floatValue = ((float)shortValue / sConst);
È stato utile?

Soluzione

Un short deve essere di almeno 16 bit, e in un sacco di implementazioni che è esattamente quello che è. Un unsigned 16 bit short terrà valori da 0 a 65535. Ciò significa che un breve non terrà ben cinque cifre di precisione, e certamente non sei. Se si desidera sei cifre, è necessario 20 bit.

Di conseguenza, qualsiasi perdita di precisione è probabilmente dovuto al fatto che si sta cercando di confezionare sei cifre di precisione in qualcosa di meno di cinque cifre. Non esiste una soluzione a questo, altro che utilizzare un tipo integrale che probabilmente prende tanto storage come float.

Non so il motivo per cui sembrerebbe al lavoro su un sistema dato. Stavi utilizzando gli stessi numeri su entrambi? Ha fatto uno utilizzano un sistema a virgola mobile più vecchio, e uno che guarda caso ha dato i risultati che ti aspettavi sui campioni provato? Era forse usando una short più grande rispetto agli altri?

Altri suggerimenti

Se si desidera utilizzare nativo di tipi in virgola mobile, il meglio che puoi fare è quello di affermare che i valori di uscita dal programma non si discosta troppo da un insieme di valori di riferimento.

La definizione precisa di "troppo" dipende dalla vostra applicazione.Per esempio, se si calcola a + b su diverse piattaforme, si dovrebbe trovare i due risultati entro la precisione di una macchina di ogni altro.D'altra parte, se si sta facendo qualcosa di più complicato come l'inversione di matrice, i risultati saranno probabilmente differiscono di più di precisione di una macchina.Determinare con precisione quanto vicino si può aspettare i risultati di ogni altro è molto sottile e complicato processo.Se non si sa esattamente cosa si sta facendo, è probabilmente il più sicuro (e più sano) per determinare il livello di precisione di cui hai bisogno a valle dell'applicazione e verificare che il risultato è sufficientemente precisa.

Per avere un'idea su come calcolare l'errore relativo tra due valori a virgola mobile robusto, vedere questa risposta e il floating point collegati in esso:

In virgola mobile funzioni di confronto per C#

Invece di usare 0xFFFF utilizzo metà, cioè 32768 per la conversione. 32768 (Ox8000) presenta una rappresentazione binaria di 1.000.000 miliardi, mentre OxFFFF ha una rappresentazione binaria della rappresentazione binaria 1111111111111111. Ox8000 s' implica chiaramente, operazioni di moltiplicazione e Divsion durante la conversione (a breve (o) mentre riconversione float) non valori di precisione cambiamento dopo lo zero. Per una conversione lato, tuttavia OxFFFF è preferibile, in quanto porta a risultati più accurati.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top