Domanda

ho un metodo che si occupa di alcune coordinate geografiche NET, e ho uno struct che memorizza una coppia di coordinate tale che se 256 viene passato a una delle coordinate, diventa 0. Tuttavia, in un caso particolare un valore di circa 255.99999998 viene calcolato, e quindi memorizzato nel struct. Quando è stampata in ToString (), diventa 256, che non dovrebbe accadere - 256 dovrebbe essere 0. Non mi dispiacerebbe se stampato 255,9999,998 mila ma il fatto che la stampa 256 quando il display del debugger 255.99999998 è un problema. Averlo sia negozio e visualizzazione 0 sarebbe ancora meglio.

In particolare c'è un problema con il confronto. 255.99999998 è sufficientemente vicino a 256 in modo tale che esso deve essere uguale esso. Cosa devo fare quando si confrontano raddoppia? utilizzare una sorta di valore epsilon?


EDIT:. In particolare, il mio problema è che io prendo un valore, eseguire alcuni calcoli, quindi eseguire i calcoli opposte su quel numero, e ho bisogno di tornare al valore originale esattamente

È stato utile?

Soluzione

È possibile utilizzare il metodo Epsilon, ma l'Epsilon è in genere un fondente per aggirare il fatto che in virgola mobile è lossy.

Si potrebbe prendere in considerazione evitando binario galleggiante punti del tutto e utilizzare una bella classe di razionale.

Il calcolo di cui sopra era probabilmente destinato ad essere 256 se si stesse facendo lossless aritmetica come si otterrebbe con un tipo razionale.

tipi razionale può andare sotto il nome di rapporto o di classe di Frazione, e sono abbastanza semplici da scrivere

Ecco un esempio . Ecco un'altra


Modifica ....

Per capire il problema considerare che quando il valore decimale 0,01 viene convertito in una rappresentazione binaria non può essere immagazzinato esattamente in memoria finita. La rappresentazione esadecimale per questo valore è 0.028F5C28F5C dove il "28F5C" ripete all'infinito. Quindi, anche prima di fare qualsiasi calcolo, si perde precisione semplicemente memorizzando 0,01 in formato binario.

classi razionali e decimali sono usati per superare questo problema, anche se con un costo delle prestazioni. tipi razionali evitare questo problema memorizzando un numeratore e un denominatore per rappresentare il vostro valore. usare tipo decimale binario codificato decimale formato , che può essere con perdita nella divisione, ma può memorizzare esattamente i valori decimali comuni.

Per il vostro scopo ho ancora suggerire un tipo razionale.

Altri suggerimenti

Questo suona come un problema con il modo il numero viene stampato, non come viene memorizzato. Un double ha circa 15 cifre significative, in modo che possa dire 255,99,999998 millions da 256 con una precisione di ricambio.

È possibile scegliere stringhe di formato che dovrebbe consentono di visualizzare la maggior quantità di numero come ti piace.

Il solito modo per confrontare doppie per l'uguaglianza è quello di sottrarre loro e vedere se il valore assoluto è inferiore a una certa epsilon predefinito, forse 0.000001.

Si deve decidere da soli su una soglia sotto la quale due valori sono uguali. Ciò equivale a effettuando le cosiddette numeri in virgola fissa (al contrario di virgola mobile). Quindi, è necessario eseguire il up rotonda manualmente.

vorrei andare con un certo tipo senza segno con dimensioni note (ad es. Uint32 o uint64 se sono disponibili, non so NET) e trattarlo come un punto di tipo numero fisso mod 256.

Eg.

typedef uint32 fixed;

inline fixed to_fixed(double d)
{
    return (fixed)(fmod(d, 256.) * (double)(1 << 24))
}

inline double to_double(fixed f)
{
    return (double)f / (double)(1 << 24);
}

o qualcosa di più elaborato per soddisfare una convenzione di arrotondamento (per più vicino, ad abbassare, al più alto, a dispari, a pari). Le più alte 8 bit di hold fissa la parte intera, i 24 bit inferiori tenere la parte frazionaria. Precisione assoluta è 2 ^ {- 24}

.

Si noti che l'aggiunta e sottraendo tali numeri si avvolge naturalmente attorno al 256. Per la moltiplicazione, si dovrebbe stare attenti.

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