2012-05-22 14 views
7

Diciamo che ho i seguenti 2 domande:SQL reale vs Float

select sum(cast(2666 as float)) * cast(.3 as float) 
select sum(cast(2666 as real)) * cast(.3 as real) 

Il 1 ° query restituisce: 799.8
Il 2 ° query restituisce: 799.800031781197

Perché la seconda query non restituire lo stesso cosa come il 1 °?

risposta

18

I tipi di punti in virgola mobile (come reali e in virgola mobile) non possono rappresentare esattamente i numeri decimali. In particolare, non è possibile memorizzare esattamente 0.3 come numero in virgola mobile binario. Invece un numero molto vicino a 0,3 viene memorizzato. Questo è chiamato errore di rappresentazione.

La dimensione dell'errore è diversa per reale e mobile perché hanno una precisione diversa.

Se si desidera memorizzare i numeri decimali in modo più accurato, prendere in considerazione l'utilizzo di decimal or numeric. Ma si noti che anche se questi tipi possono memorizzare accuratamente i valori decimali fino a un certo numero di cifre, i calcoli possono ancora produrre numeri che non possono essere rappresentati esattamente. Ad esempio, il risultato di 0.1/0.3 non può essere memorizzato esattamente in un decimal, anche se sia lo 0.1 sia lo 0.3 possono. In questo caso il risultato sarà arrotondato al valore più vicino che può essere memorizzato nel tipo (ad esempio 0.333333333 a seconda della precisione).

+2

Sì, proprio come 1/3 è un numero ricorrente in decimale (0,333333 ... per sempre), è anche ricorrente in binario: 0,01010101010101 --- per sempre. Tuttavia, alcuni numeri non ricorrenti in decimale, come 0.1, sono ricorrenti in binario. Per esempio. 0.1dec = 0.0001100110011 ... per sempre in binario, e quindi non può essere rappresentato esattamente. – DaveBoltman