Domanda

Dopo un'ora di cercare di trovare un bug nel mio codice ho finalmente trovato la ragione. Stavo cercando di aggiungere un piccolo galleggiante a 1F, ma nulla stesse accadendo. Mentre si cerca di capire il motivo per cui ho scoperto che l'aggiunta di quel piccolo galleggiante 0f ha funzionato perfettamente.

Perché succede questo? Questo ha a che fare con 'ordini di grandezza'? C'è qualche soluzione a questo problema?

Grazie in anticipo.

Modifica:

Il passaggio alla doppia precisione o decimale non è un'opzione in questo momento.

È stato utile?

Soluzione

Poiché precisione per una singola precisione (32 bit) valore a virgola mobile è di circa 7 cifre dopo il punto decimale. Il che significa che il valore che si aggiunge è essenzialmente pari a zero, almeno quando aggiunto al 1. Il valore stesso, tuttavia, può facilmente immagazzinato in un galleggiante poiché l'esponente è piccolo in quel caso. Ma per aggiungere con successo a 1 è necessario utilizzare l'esponente del numero più grande ... e poi le cifre dopo gli zeri scompaiono in arrotondamento.

È possibile utilizzare double se avete bisogno di una maggiore precisione. Performance-wise questo non dovrebbe fare la differenza su hardware e la memoria di oggi è spesso anche non come vincoli che si deve pensare a ogni singola variabile.

Modifica Come lei ha affermato che l'uso double non è un'opzione è possibile utilizzare Kahan sommatoria , come akuhn sottolineato in un commento.

Un'altra opzione potrebbe essere quella di eseguire calcoli intermedi in doppia precisione e successiva semplice per float nuovamente. Questo sarà solo aiutare, tuttavia, quando ci sono un paio di operazioni di una semplice aggiunta di un numero molto piccolo ad uno più grande.

Altri suggerimenti

Ciò accade probabilmente perché il numero di cifre di precisione in un galleggiante è costante, ma l'esponente può ovviamente variare.

Ciò significa che, anche se è possibile aggiungere il numero di piccole e 0, non si può pretendere di aggiungerlo a un numero che ha un esponente diverso da 0, in quanto lì solo non sarà sufficiente cifre di precisione a sinistra.

Si consiglia di leggere Ciò che ogni computer Scientist dovrebbe sapere aritmetica alla virgola mobile .

Sembra che abbia qualcosa a che fare con precisione in virgola mobile. Se fossi in te, mi piacerebbe usare un tipo diverso, come decimal. Questo dovrebbe correggere gli errori di precisione.

Con float, si ottiene solo un precisione di circa sette cifre . Così il vostro number'll essere arrotondato in 1f. Se si desidera memorizzare tale numero, usare double invece

http://msdn.microsoft.com/en-us/library /ayazw934.aspx

In aggiunta alla risposta accettata: Se avete bisogno di riassumere molte piccole serie e alcuni tra quelli più grandi, è necessario utilizzare Kahan sommatoria .

Se le prestazioni sono un problema (perché non è possibile utilizzare double), quindi scala binaria / fisso punto può essere un'opzione. floats sono memorizzati come numeri interi, ma in scala da un gran numero (ad esempio, 2 ^ 16). aritmetica intermedio è fatto con operazioni (relativamente veloce) interi. La risposta finale può essere riconvertito in virgola mobile alla fine, dividendo per il fattore di scala.

Questo è spesso fatto se il processore target manca un'unità di calcolo in virgola mobile hardware.

Si sta usando il suffisso F sulla letterali, che renderanno questi carri, invece di doppie. Così il vostro molto piccolo galleggiante svanirà nel galleggiante più grande.

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